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