2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * @(#)refresh.c 8.1 (Berkeley) 6/4/93
40 * refresh.c: Lower level screen refreshing functions
49 private void re_addc __P((EditLine *, int));
50 private void re_update_line __P((EditLine *, char *, char *, int));
51 private void re_insert __P((EditLine *, char *, int, int,
53 private void re_delete __P((EditLine *, char *, int, int,
55 private void re_fastputc __P((EditLine *, int));
57 private void re__strncopy __P((char *, char *, size_t));
58 private void re__copy_and_pad __P((char *, char *, size_t));
61 private void re_printstr __P((EditLine *, char *, char *,
63 # define __F el->el_errfile
64 # define RE_DEBUG(a, b, c) do \
71 * Print a string on the debugging pty
74 re_printstr(el, str, f, t)
79 RE_DEBUG(1,(__F, "%s:\"", str),);
81 RE_DEBUG(1,(__F, "%c", *f++ & 0177),);
82 RE_DEBUG(1,(__F, "\"\r\n"),);
85 # define RE_DEBUG(a, b, c)
90 * Draw c, expanding tabs, control chars etc.
103 if (c == '\n') { /* expand the newline */
104 re_putc(el, '\0'); /* assure end of line */
105 el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
106 el->el_refresh.r_cursor.v++;
109 if (c == '\t') { /* expand the tab */
112 if ((el->el_refresh.r_cursor.h & 07) == 0)
113 break; /* go until tab stop */
116 else if (iscntrl(c)) {
121 /* uncontrolify it; works only for iso8859-1 like sets */
122 re_putc(el, (toascii(c) | 0100));
126 re_putc(el, ((c >> 6) & 07) + '0');
127 re_putc(el, ((c >> 3) & 07) + '0');
128 re_putc(el, (c & 07) + '0');
134 * Draw the character given
141 RE_DEBUG(1,(__F, "printing %3.3o '%c'\r\n", c, c),);
143 el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
144 el->el_refresh.r_cursor.h++; /* advance to next place */
145 if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
146 el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
147 /* assure end of line */
148 el->el_refresh.r_cursor.h = 0; /* reset it. */
149 el->el_refresh.r_cursor.v++;
150 RE_DEBUG(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
151 (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
152 el->el_refresh.r_cursor.v, el->el_term.t_size.v), abort());
158 * draws the new virtual screen image from the current input
159 * line, then goes line-by-line changing the real image to the new
160 * virtual image. The routine to re-draw a line can be replaced
161 * easily in hopes of a smarter one being placed there.
171 RE_DEBUG(1,(__F, "el->el_line.buffer = :%s:\r\n", el->el_line.buffer),);
173 /* reset the Drawing cursor */
174 el->el_refresh.r_cursor.h = 0;
175 el->el_refresh.r_cursor.v = 0;
177 cur.h = -1; /* set flag in case I'm not set */
182 /* draw the current input buffer */
183 for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
184 if (cp == el->el_line.cursor) {
185 cur.h = el->el_refresh.r_cursor.h; /* save for later */
186 cur.v = el->el_refresh.r_cursor.v;
191 if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
192 cur.h = el->el_refresh.r_cursor.h;
193 cur.v = el->el_refresh.r_cursor.v;
195 /* must be done BEFORE the NUL is written */
196 el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
197 re_putc(el, '\0'); /* put NUL on end */
200 "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
201 el->el_term.t_size.h, el->el_refresh.r_cursor.h,
202 el->el_refresh.r_cursor.v, el->el_vdisplay[0]),);
204 RE_DEBUG(1,(__F, "updating %d lines.\r\n", el->el_refresh.r_newcv),);
205 for (i = 0; i <= el->el_refresh.r_newcv; i++) {
206 /* NOTE THAT re_update_line MAY CHANGE el_display[i] */
207 re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
210 * Copy the new line to be the current one, and pad out with spaces
211 * to the full width of the terminal so that if we try moving the
212 * cursor by writing the character that is at the end of the
213 * screen line, it won't be a NUL or some old leftover stuff.
215 re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
216 el->el_term.t_size.h);
219 "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
220 el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i),);
222 if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
223 for (; i <= el->el_refresh.r_oldcv; i++) {
224 term_move_to_line(el, i);
225 term_move_to_char(el, 0);
226 term_clear_EOL(el, strlen(el->el_display[i]));
228 term_overwrite(el, "C\b", 2);
229 #endif /* DEBUG_REFRESH */
230 *el->el_display[i] = '\0';
233 el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
235 "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
236 el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
238 term_move_to_line(el, cur.v); /* go to where the cursor is */
239 term_move_to_char(el, cur.h);
240 } /* end re_refresh */
244 * used to go to last used screen line
250 term_move_to_line(el, el->el_refresh.r_oldcv);
253 re_clear_display(el);
255 } /* end re_goto_bottom */
259 * insert num characters of s into d (in front of the character)
260 * at dat, maximum length of d is dlen
264 re_insert(el, d, dat, dlen, s, num)
275 if (num > dlen - dat)
278 RE_DEBUG(1,(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
279 num, dat, dlen, d),);
280 RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
282 /* open up the space for num chars */
288 d[dlen] = '\0'; /* just in case */
291 "re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
292 num, dat, dlen, d),);
293 RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
295 /* copy the characters */
296 for (a = d + dat; (a < d + dlen) && (num > 0); num--)
299 RE_DEBUG(1,(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
300 num, dat, dlen, d, s),);
301 RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
302 } /* end re_insert */
306 * delete num characters d at dat, maximum length of d is dlen
310 re_delete(el, d, dat, dlen, num)
319 if (dat + num >= dlen) {
324 RE_DEBUG(1,(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
325 num, dat, dlen, d),);
327 /* open up the space for num chars */
333 d[dlen] = '\0'; /* just in case */
335 RE_DEBUG(1,(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
336 num, dat, dlen, d),);
337 } /* end re_delete */
341 * Like strncpy without padding.
344 re__strncopy(a, b, n)
350 } /* end re__strncopy */
353 /* ****************************************************************
354 re_update_line() is based on finding the middle difference of each line
357 /old first difference
358 /beginning of line | /old last same /old EOL
360 old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
361 new: eddie> Oh, my little buggy says to me, as lurgid as
363 \beginning of line | \new last same \new end of line
364 \new first difference
366 all are character pointers for the sake of speed. Special cases for
367 no differences, as well as for end of line additions must be handled.
368 **************************************************************** */
370 /* Minimum at which doing an insert it "worth it". This should be about
371 * half the "cost" of going into insert mode, inserting a character, and
372 * going back out. This should really be calculated from the termcap
373 * data... For the moment, a good number for ANSI terminals.
375 #define MIN_END_KEEP 4
378 re_update_line(el, old, new, i)
384 char *ofd, *ols, *oe, *nfd, *nls, *ne;
385 char *osb, *ose, *nsb, *nse;
391 for (o = old, n = new; *o && (*o == *n); o++, n++)
397 * Find the end of both old and new
402 * Remove any trailing blanks off of the end, being careful not to
403 * back up past the beginning.
416 /* remove blanks from end of new */
426 * if no diff, continue to next line of redraw
428 if (*ofd == '\0' && *nfd == '\0') {
429 RE_DEBUG(1,(__F, "no difference.\r\n"),);
434 * find last same pointer
436 while ((o > ofd) && (n > nfd) && (*--o == *--n))
442 * find same begining and same end
450 * case 1: insert: scan from nfd to nls looking for *ofd
453 for (c = *ofd, n = nfd; n < nls; n++) {
455 for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++)
458 * if the new match is longer and it's worth keeping, then we
461 if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) {
472 * case 2: delete: scan from ofd to ols looking for *nfd
475 for (c = *nfd, o = ofd; o < ols; o++) {
477 for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++)
480 * if the new match is longer and it's worth keeping, then we
483 if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) {
494 * Pragmatics I: If old trailing whitespace or not enough characters to
495 * save to be worth it, then don't save the last same info.
497 if ((oe - ols) < MIN_END_KEEP) {
503 * Pragmatics II: if the terminal isn't smart enough, make the data dumber
504 * so the smart update doesn't try anything fancy
508 * fx is the number of characters we need to insert/delete: in the
509 * beginning to bring the two same begins together
511 fx = (nsb - nfd) - (osb - ofd);
513 * sx is the number of characters we need to insert/delete: in the end to
514 * bring the two same last parts together
516 sx = (nls - nse) - (ols - ose);
518 if (!EL_CAN_INSERT) {
529 if ((ols - ofd) < (nls - nfd)) {
534 if (!EL_CAN_DELETE) {
545 if ((ols - ofd) > (nls - nfd)) {
552 * Pragmatics III: make sure the middle shifted pointers are correct if
553 * they don't point to anything (we may have moved ols or nls).
555 /* if the change isn't worth it, don't bother */
556 /* was: if (osb == ose) */
557 if ((ose - osb) < MIN_END_KEEP) {
565 * Now that we are done with pragmatics we recompute fx, sx
567 fx = (nsb - nfd) - (osb - ofd);
568 sx = (nls - nse) - (ols - ose);
570 RE_DEBUG(1,(__F, "\n"),);
571 RE_DEBUG(1,(__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
572 ofd - old, osb - old, ose - old, ols - old, oe - old),);
573 RE_DEBUG(1,(__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
574 nfd - new, nsb - new, nse - new, nls - new, ne - new),);
576 "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"),);
578 "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"),);
580 re_printstr(el, "old- oe", old, oe);
581 re_printstr(el, "new- ne", new, ne);
582 re_printstr(el, "old-ofd", old, ofd);
583 re_printstr(el, "new-nfd", new, nfd);
584 re_printstr(el, "ofd-osb", ofd, osb);
585 re_printstr(el, "nfd-nsb", nfd, nsb);
586 re_printstr(el, "osb-ose", osb, ose);
587 re_printstr(el, "nsb-nse", nsb, nse);
588 re_printstr(el, "ose-ols", ose, ols);
589 re_printstr(el, "nse-nls", nse, nls);
590 re_printstr(el, "ols- oe", ols, oe);
591 re_printstr(el, "nls- ne", nls, ne);
592 #endif /* DEBUG_REFRESH */
595 * el_cursor.v to this line i MUST be in this routine so that if we
596 * don't have to change the line, we don't move to it. el_cursor.h to first
599 term_move_to_line(el, i);
602 * at this point we have something like this:
604 * /old /ofd /osb /ose /ols /oe
605 * v.....................v v..................v v........v
606 * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
607 * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
608 * ^.....................^ ^..................^ ^........^
609 * \new \nfd \nsb \nse \nls \ne
611 * fx is the difference in length between the the chars between nfd and
612 * nsb, and the chars between ofd and osb, and is thus the number of
613 * characters to delete if < 0 (new is shorter than old, as above),
614 * or insert (new is longer than short).
616 * sx is the same for the second differences.
620 * if we have a net insert on the first difference, AND inserting the net
621 * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character
622 * (which is ne if nls != ne, otherwise is nse) off the edge of the screen
623 * (el->el_term.t_size.h) else we do the deletes first so that we keep everything we need
628 * if the last same is the same like the end, there is no last same part,
629 * otherwise we want to keep the last same part set p to the last useful
632 p = (ols != oe) ? oe : ose;
635 * if (There is a diffence in the beginning) && (we need to insert
636 * characters) && (the number of characters to insert is less than the term
637 * width) We need to do an insert! else if (we need to delete characters)
638 * We need to delete characters! else No insert or delete
640 if ((nsb != nfd) && fx > 0 && ((p - old) + fx <= el->el_term.t_size.h)) {
641 RE_DEBUG(1,(__F, "first diff insert at %d...\r\n", nfd - new),);
643 * Move to the first char to insert, where the first diff is.
645 term_move_to_char(el, nfd - new);
647 * Check if we have stuff to keep at end
650 RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
652 * insert fx chars of new starting at nfd
655 RE_DEBUG(!EL_CAN_INSERT,
656 (__F, "ERROR: cannot insert in early first diff\n"),);
657 term_insertwrite(el, nfd, fx);
658 re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
661 * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
663 term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
664 re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
667 RE_DEBUG(1,(__F, "without anything to save\r\n"),);
668 term_overwrite(el, nfd, (nsb - nfd));
669 re__strncopy(ofd, nfd, (nsb - nfd));
677 RE_DEBUG(1,(__F, "first diff delete at %d...\r\n", ofd - old),);
679 * move to the first char to delete where the first diff is
681 term_move_to_char(el, ofd - old);
683 * Check if we have stuff to save
686 RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
688 * fx is less than zero *always* here but we check for code
692 RE_DEBUG(!EL_CAN_DELETE,
693 (__F, "ERROR: cannot delete in first diff\n"),);
694 term_deletechars(el, -fx);
695 re_delete(el, old, ofd - old, el->el_term.t_size.h, -fx);
698 * write (nsb-nfd) chars of new starting at nfd
700 term_overwrite(el, nfd, (nsb - nfd));
701 re__strncopy(ofd, nfd, (nsb - nfd));
705 RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
707 * write (nsb-nfd) chars of new starting at nfd
709 term_overwrite(el, nfd, (nsb - nfd));
710 RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
711 term_clear_EOL(el, (oe - old) - (ne - new));
722 RE_DEBUG(1,(__F, "second diff delete at %d...\r\n", (ose - old) + fx),);
724 * Check if we have stuff to delete
727 * fx is the number of characters inserted (+) or deleted (-)
730 term_move_to_char(el, (ose - old) + fx);
732 * Check if we have stuff to save
735 RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
737 * Again a duplicate test.
740 RE_DEBUG(!EL_CAN_DELETE,
741 (__F, "ERROR: cannot delete in second diff\n"),);
742 term_deletechars(el, -sx);
746 * write (nls-nse) chars of new starting at nse
748 term_overwrite(el, nse, (nls - nse));
751 RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
752 term_overwrite(el, nse, (nls - nse));
753 RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
754 term_clear_EOL(el, (oe - old) - (ne - new));
759 * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
761 if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
762 RE_DEBUG(1,(__F, "late first diff insert at %d...\r\n", nfd - new),);
764 term_move_to_char(el, nfd - new);
766 * Check if we have stuff to keep at the end
769 RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
771 * We have to recalculate fx here because we set it
772 * to zero above as a flag saying that we hadn't done
773 * an early first insert.
775 fx = (nsb - nfd) - (osb - ofd);
778 * insert fx chars of new starting at nfd
780 RE_DEBUG(!EL_CAN_INSERT,
781 (__F, "ERROR: cannot insert in late first diff\n"),);
782 term_insertwrite(el, nfd, fx);
783 re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
787 * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
789 term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
790 re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
793 RE_DEBUG(1,(__F, "without anything to save\r\n"),);
794 term_overwrite(el, nfd, (nsb - nfd));
795 re__strncopy(ofd, nfd, (nsb - nfd));
800 * line is now NEW up to nse
803 RE_DEBUG(1,(__F, "second diff insert at %d...\r\n", nse - new),);
804 term_move_to_char(el, nse - new);
806 RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
808 /* insert sx chars of new starting at nse */
809 RE_DEBUG(!EL_CAN_INSERT,
810 (__F, "ERROR: cannot insert in second diff\n"),);
811 term_insertwrite(el, nse, sx);
815 * write (nls-nse) - sx chars of new starting at (nse + sx)
817 term_overwrite(el, nse + sx, (nls - nse) - sx);
820 RE_DEBUG(1,(__F, "without anything to save\r\n"),);
821 term_overwrite(el, nse, (nls - nse));
824 * No need to do a clear-to-end here because we were doing
825 * a second insert, so we will have over written all of the
830 RE_DEBUG(1,(__F, "done.\r\n"),);
831 } /* re_update_line */
834 /* re__copy_and_pad():
835 * Copy string and pad with spaces
838 re__copy_and_pad(dst, src, width)
844 for (i = 0; i < width; i++) {
855 } /* end re__copy_and_pad */
858 /* re_refresh_cursor():
859 * Move to the new cursor position
862 re_refresh_cursor(el)
869 /* first we must find where the cursor is... */
870 h = el->el_prompt.p_pos.h;
871 v = el->el_prompt.p_pos.v;
872 th = el->el_term.t_size.h; /* optimize for speed */
874 /* do input buffer to el->el_line.cursor */
875 for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
876 c = (unsigned char)*cp;
877 h++; /* all chars at least this long */
879 if (c == '\n') { /* handle newline in data part too */
884 if (c == '\t') { /* if a tab, to next tab stop */
889 else if (iscntrl(c)) { /* if control char */
891 if (h > th) { /* if overflow, compensate */
896 else if (!isprint(c)) {
898 if (h > th) { /* if overflow, compensate */
905 if (h >= th) { /* check, extra long tabs picked up here also */
912 term_move_to_line(el, v);
913 term_move_to_char(el, h);
915 } /* re_refresh_cursor */
919 * Add a character fast.
927 el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
928 if (el->el_cursor.h >= el->el_term.t_size.h) {
929 /* if we must overflow */
932 el->el_refresh.r_oldcv++;
936 } /* end re_fastputc */
940 * we added just one char, handle it fast.
941 * Assumes that screen cursor == real cursor
949 c = (unsigned char)el->el_line.cursor[-1];
951 if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
952 re_refresh(el); /* too hard to handle */
954 } /* else (only do at end of line, no TAB) */
956 if (iscntrl(c)) { /* if control char, do caret */
957 char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
958 re_fastputc(el, '^');
961 else if (isprint(c)) { /* normal char */
965 re_fastputc(el, '\\');
966 re_fastputc(el, ((c >> 6) & 7) + '0');
967 re_fastputc(el, ((c >> 3) & 7) + '0');
968 re_fastputc(el, (c & 7) + '0');
971 } /* end re_fastaddc */
974 /* re_clear_display():
975 * clear the screen buffers so that new new prompt starts fresh.
985 for (i = 0; i < el->el_term.t_size.v; i++)
986 el->el_display[i][0] = '\0';
987 el->el_refresh.r_oldcv = 0;
988 } /* end re_clear_display */
992 * Make sure all lines are *really* blank
1000 term_move_to_char(el, 0);
1001 for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
1002 /* for each line on the screen */
1003 term_move_to_line(el, i);
1004 term_clear_EOL(el, el->el_term.t_size.h);
1006 term_move_to_line(el, 0);
1009 term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */
1010 term__putc('\r'); /* go to BOL */
1011 term__putc('\n'); /* go to new line */
1013 } /* end re_clear_lines */