summaryrefslogtreecommitdiffstats
path: root/lib/libedit/refresh.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-10-01 08:41:27 +0000
committerobrien <obrien@FreeBSD.org>2001-10-01 08:41:27 +0000
commit90300f853673b3879ab4d6a60683ff69b564c58b (patch)
treef9436ba88ca8f8420af319b0a12dd175381b507b /lib/libedit/refresh.c
parentf805e363ed51ace3356b37eb173c3d6435c35022 (diff)
downloadFreeBSD-src-90300f853673b3879ab4d6a60683ff69b564c58b.zip
FreeBSD-src-90300f853673b3879ab4d6a60683ff69b564c58b.tar.gz
+ Sync with NetBSD, bringing in feature enhancements.
+ Convert to ANSI-C function definitions + style(9) Submitted by: kris
Diffstat (limited to 'lib/libedit/refresh.c')
-rw-r--r--lib/libedit/refresh.c1640
1 files changed, 864 insertions, 776 deletions
diff --git a/lib/libedit/refresh.c b/lib/libedit/refresh.c
index 567491e..3be9e2c 100644
--- a/lib/libedit/refresh.c
+++ b/lib/libedit/refresh.c
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $NetBSD: refresh.c,v 1.16 2001/01/10 07:45:42 jdolecek Exp $
*/
#include <sys/cdefs.h>
@@ -39,6 +41,8 @@ __FBSDID("$FreeBSD$");
#if !defined(lint) && !defined(SCCSID)
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint && not SCCSID */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
/*
* refresh.c: Lower level screen refreshing functions
@@ -50,43 +54,40 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#include "el.h"
-private void re_addc __P((EditLine *, int));
-private void re_update_line __P((EditLine *, char *, char *, int));
-private void re_insert __P((EditLine *, char *, int, int,
- char *, int));
-private void re_delete __P((EditLine *, char *, int, int,
- int));
-private void re_fastputc __P((EditLine *, int));
-
-private void re__strncopy __P((char *, char *, size_t));
-private void re__copy_and_pad __P((char *, char *, size_t));
+private void re_addc(EditLine *, int);
+private void re_update_line(EditLine *, char *, char *, int);
+private void re_insert (EditLine *, char *, int, int, char *, int);
+private void re_delete(EditLine *, char *, int, int, int);
+private void re_fastputc(EditLine *, int);
+private void re__strncopy(char *, char *, size_t);
+private void re__copy_and_pad(char *, char *, size_t);
#ifdef DEBUG_REFRESH
-private void re_printstr __P((EditLine *, char *, char *,
- char *));
-# define __F el->el_errfile
-# define RE_DEBUG(a, b, c) do \
+private void re_printstr(EditLine *, char *, char *, char *);
+#define __F el->el_errfile
+#define ELRE_ASSERT(a, b, c) do \
if (a) { \
(void) fprintf b; \
c; \
} \
while (0)
+#define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;)
+
/* re_printstr():
* Print a string on the debugging pty
*/
private void
-re_printstr(el, str, f, t)
- EditLine *el;
- char *str;
- char *f, *t;
+re_printstr(EditLine *el, char *str, char *f, char *t)
{
- RE_DEBUG(1,(__F, "%s:\"", str),);
- while (f < t)
- RE_DEBUG(1,(__F, "%c", *f++ & 0177),);
- RE_DEBUG(1,(__F, "\"\r\n"),);
+
+ ELRE_DEBUG(1, (__F, "%s:\"", str));
+ while (f < t)
+ ELRE_DEBUG(1, (__F, "%c", *f++ & 0177));
+ ELRE_DEBUG(1, (__F, "\"\r\n"));
}
#else
-# define RE_DEBUG(a, b, c)
+#define ELRE_ASSERT(a, b, c)
+#define ELRE_DEBUG(a, b)
#endif
@@ -94,68 +95,89 @@ re_printstr(el, str, f, t)
* Draw c, expanding tabs, control chars etc.
*/
private void
-re_addc(el, c)
- EditLine *el;
- int c;
+re_addc(EditLine *el, int c)
{
- c = (unsigned char)c;
-
- if (isprint(c)) {
- re_putc(el, c);
- return;
- }
- if (c == '\n') { /* expand the newline */
- re_putc(el, '\0'); /* assure end of line */
- el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
- el->el_refresh.r_cursor.v++;
- return;
- }
- if (c == '\t') { /* expand the tab */
- for (;;) {
- re_putc(el, ' ');
- if ((el->el_refresh.r_cursor.h & 07) == 0)
- break; /* go until tab stop */
+
+ c = (unsigned char)c;
+
+ if (isprint(c)) {
+ re_putc(el, c, 1);
+ return;
}
- }
- else if (iscntrl(c)) {
- re_putc(el, '^');
- if (c == 0177)
- re_putc(el, '?');
- else
- /* uncontrolify it; works only for iso8859-1 like sets */
- re_putc(el, (toascii(c) | 0100));
- }
- else {
- re_putc(el, '\\');
- re_putc(el, ((c >> 6) & 07) + '0');
- re_putc(el, ((c >> 3) & 07) + '0');
- re_putc(el, (c & 07) + '0');
- }
-} /* end re_addc */
+ if (c == '\n') { /* expand the newline */
+ int oldv = el->el_refresh.r_cursor.v;
+ re_putc(el, '\0', 0); /* assure end of line */
+ if (oldv == el->el_refresh.r_cursor.v) { /* XXX */
+ el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
+ el->el_refresh.r_cursor.v++;
+ }
+ return;
+ }
+ if (c == '\t') { /* expand the tab */
+ for (;;) {
+ re_putc(el, ' ', 1);
+ if ((el->el_refresh.r_cursor.h & 07) == 0)
+ break; /* go until tab stop */
+ }
+ } else if (iscntrl(c)) {
+ re_putc(el, '^', 1);
+ if (c == 0177)
+ re_putc(el, '?', 1);
+ else
+ /* uncontrolify it; works only for iso8859-1 like sets */
+ re_putc(el, (toascii(c) | 0100), 1);
+ } else {
+ re_putc(el, '\\', 1);
+ re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1);
+ re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1);
+ re_putc(el, (c & 07) + '0', 1);
+ }
+}
/* re_putc():
* Draw the character given
*/
protected void
-re_putc(el, c)
- EditLine *el;
- int c;
+re_putc(EditLine *el, int c, int shift)
{
- RE_DEBUG(1,(__F, "printing %3.3o '%c'\r\n", c, c),);
-
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
- el->el_refresh.r_cursor.h++; /* advance to next place */
- if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
- /* assure end of line */
- el->el_refresh.r_cursor.h = 0; /* reset it. */
- el->el_refresh.r_cursor.v++;
- RE_DEBUG(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
- (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
- el->el_refresh.r_cursor.v, el->el_term.t_size.v), abort());
- }
-} /* end re_putc */
+
+ ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c));
+
+ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
+ if (!shift)
+ return;
+
+ el->el_refresh.r_cursor.h++; /* advance to next place */
+ if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
+ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
+ /* assure end of line */
+ el->el_refresh.r_cursor.h = 0; /* reset it. */
+
+ /*
+ * If we would overflow (input is longer than terminal size),
+ * emulate scroll by dropping first line and shuffling the rest.
+ * We do this via pointer shuffling - it's safe in this case
+ * and we avoid memcpy().
+ */
+ if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
+ int i, lins = el->el_term.t_size.v;
+ char *firstline = el->el_vdisplay[0];
+
+ for(i=1; i < lins; i++)
+ el->el_vdisplay[i-1] = el->el_vdisplay[i];
+
+ firstline[0] = '\0'; /* empty the string */
+ el->el_vdisplay[i-1] = firstline;
+ } else
+ el->el_refresh.r_cursor.v++;
+
+ ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
+ (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
+ el->el_refresh.r_cursor.v, el->el_term.t_size.v),
+ abort());
+ }
+}
/* re_refresh():
@@ -165,98 +187,143 @@ re_putc(el, c)
* easily in hopes of a smarter one being placed there.
*/
protected void
-re_refresh(el)
- EditLine *el;
+re_refresh(EditLine *el)
{
- int i;
- char *cp;
- coord_t cur;
+ int i, rhdiff;
+ char *cp, *st;
+ coord_t cur;
+#ifdef notyet
+ size_t termsz;
+#endif
+
+ ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n",
+ el->el_line.buffer));
+
+ /* reset the Drawing cursor */
+ el->el_refresh.r_cursor.h = 0;
+ el->el_refresh.r_cursor.v = 0;
- RE_DEBUG(1,(__F, "el->el_line.buffer = :%s:\r\n", el->el_line.buffer),);
+ /* temporarily draw rprompt to calculate its size */
+ prompt_print(el, EL_RPROMPT);
- /* reset the Drawing cursor */
- el->el_refresh.r_cursor.h = 0;
- el->el_refresh.r_cursor.v = 0;
+ /* reset the Drawing cursor */
+ el->el_refresh.r_cursor.h = 0;
+ el->el_refresh.r_cursor.v = 0;
- cur.h = -1; /* set flag in case I'm not set */
- cur.v = 0;
+ cur.h = -1; /* set flag in case I'm not set */
+ cur.v = 0;
- prompt_print(el);
+ prompt_print(el, EL_PROMPT);
+
+ /* draw the current input buffer */
+#if notyet
+ termsz = el->el_term.t_size.h * el->el_term.t_size.v;
+ if (el->el_line.lastchar - el->el_line.buffer > termsz) {
+ /*
+ * If line is longer than terminal, process only part
+ * of line which would influence display.
+ */
+ size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
- /* draw the current input buffer */
- for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
- if (cp == el->el_line.cursor) {
- cur.h = el->el_refresh.r_cursor.h; /* save for later */
- cur.v = el->el_refresh.r_cursor.v;
+ st = el->el_line.lastchar - rem
+ - (termsz - (((rem / el->el_term.t_size.v) - 1)
+ * el->el_term.t_size.v));
+ } else
+#endif
+ st = el->el_line.buffer;
+
+ for (cp = st; cp < el->el_line.lastchar; cp++) {
+ if (cp == el->el_line.cursor) {
+ /* save for later */
+ cur.h = el->el_refresh.r_cursor.h;
+ cur.v = el->el_refresh.r_cursor.v;
+ }
+ re_addc(el, (unsigned char) *cp);
}
- re_addc(el, *cp);
- }
-
- if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
- cur.h = el->el_refresh.r_cursor.h;
- cur.v = el->el_refresh.r_cursor.v;
- }
- /* must be done BEFORE the NUL is written */
- el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
- re_putc(el, '\0'); /* put NUL on end */
-
- RE_DEBUG(1,(__F,
- "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
- el->el_term.t_size.h, el->el_refresh.r_cursor.h,
- el->el_refresh.r_cursor.v, el->el_vdisplay[0]),);
-
- RE_DEBUG(1,(__F, "updating %d lines.\r\n", el->el_refresh.r_newcv),);
- for (i = 0; i <= el->el_refresh.r_newcv; i++) {
- /* NOTE THAT re_update_line MAY CHANGE el_display[i] */
- re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
- /*
- * Copy the new line to be the current one, and pad out with spaces
- * to the full width of the terminal so that if we try moving the
- * cursor by writing the character that is at the end of the
- * screen line, it won't be a NUL or some old leftover stuff.
- */
- re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
- el->el_term.t_size.h);
- }
- RE_DEBUG(1,(__F,
- "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
- el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i),);
-
- if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
- for (; i <= el->el_refresh.r_oldcv; i++) {
- term_move_to_line(el, i);
- term_move_to_char(el, 0);
- term_clear_EOL(el, strlen(el->el_display[i]));
+ if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
+ cur.h = el->el_refresh.r_cursor.h;
+ cur.v = el->el_refresh.r_cursor.v;
+ }
+ rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h -
+ el->el_rprompt.p_pos.h;
+ if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
+ !el->el_refresh.r_cursor.v && rhdiff > 1) {
+ /*
+ * have a right-hand side prompt that will fit
+ * on the end of the first line with at least
+ * one character gap to the input buffer.
+ */
+ while (--rhdiff > 0) /* pad out with spaces */
+ re_putc(el, ' ', 1);
+ prompt_print(el, EL_RPROMPT);
+ } else {
+ el->el_rprompt.p_pos.h = 0; /* flag "not using rprompt" */
+ el->el_rprompt.p_pos.v = 0;
+ }
+
+ re_putc(el, '\0', 0); /* make line ended with NUL, no cursor shift */
+
+ el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
+
+ ELRE_DEBUG(1, (__F,
+ "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
+ el->el_term.t_size.h, el->el_refresh.r_cursor.h,
+ el->el_refresh.r_cursor.v, el->el_vdisplay[0]));
+
+ ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
+ for (i = 0; i <= el->el_refresh.r_newcv; i++) {
+ /* NOTE THAT re_update_line MAY CHANGE el_display[i] */
+ re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
+
+ /*
+ * Copy the new line to be the current one, and pad out with
+ * spaces to the full width of the terminal so that if we try
+ * moving the cursor by writing the character that is at the
+ * end of the screen line, it won't be a NUL or some old
+ * leftover stuff.
+ */
+ re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
+ (size_t) el->el_term.t_size.h);
+ }
+ ELRE_DEBUG(1, (__F,
+ "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
+ el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));
+
+ if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
+ for (; i <= el->el_refresh.r_oldcv; i++) {
+ term_move_to_line(el, i);
+ term_move_to_char(el, 0);
+ term_clear_EOL(el, (int) strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH
- term_overwrite(el, "C\b", 2);
+ term_overwrite(el, "C\b", 2);
#endif /* DEBUG_REFRESH */
- *el->el_display[i] = '\0';
- }
+ el->el_display[i][0] = '\0';
+ }
- el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
- RE_DEBUG(1,(__F,
- "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
- el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
- cur.h, cur.v),);
- term_move_to_line(el, cur.v); /* go to where the cursor is */
- term_move_to_char(el, cur.h);
-} /* end re_refresh */
+ el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
+ ELRE_DEBUG(1, (__F,
+ "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
+ el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
+ cur.h, cur.v));
+ term_move_to_line(el, cur.v); /* go to where the cursor is */
+ term_move_to_char(el, cur.h);
+}
/* re_goto_bottom():
* used to go to last used screen line
*/
protected void
-re_goto_bottom(el)
- EditLine *el;
+re_goto_bottom(EditLine *el)
{
- term_move_to_line(el, el->el_refresh.r_oldcv);
- term__putc('\r');
- term__putc('\n');
- re_clear_display(el);
- term__flush();
-} /* end re_goto_bottom */
+
+ term_move_to_line(el, el->el_refresh.r_oldcv);
+ term__putc('\r');
+ term__putc('\n');
+ re_clear_display(el);
+ term__flush();
+}
/* re_insert():
@@ -265,45 +332,42 @@ re_goto_bottom(el)
*/
private void
/*ARGSUSED*/
-re_insert(el, d, dat, dlen, s, num)
- EditLine *el;
- char *d;
- int dat, dlen;
- char *s;
- int num;
+re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num)
{
- char *a, *b;
-
- if (num <= 0)
- return;
- if (num > dlen - dat)
- num = dlen - dat;
-
- RE_DEBUG(1,(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d),);
- RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
-
- /* open up the space for num chars */
- if (num > 0) {
- b = d + dlen - 1;
- a = b - num;
- while (a >= &d[dat])
- *b-- = *a--;
- d[dlen] = '\0'; /* just in case */
- }
- RE_DEBUG(1,(__F,
+ char *a, *b;
+
+ if (num <= 0)
+ return;
+ if (num > dlen - dat)
+ num = dlen - dat;
+
+ ELRE_DEBUG(1,
+ (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d));
+ ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
+
+ /* open up the space for num chars */
+ if (num > 0) {
+ b = d + dlen - 1;
+ a = b - num;
+ while (a >= &d[dat])
+ *b-- = *a--;
+ d[dlen] = '\0'; /* just in case */
+ }
+ ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d),);
- RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
+ num, dat, dlen, d));
+ ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
- /* copy the characters */
- for (a = d + dat; (a < d + dlen) && (num > 0); num--)
- *a++ = *s++;
+ /* copy the characters */
+ for (a = d + dat; (a < d + dlen) && (num > 0); num--)
+ *a++ = *s++;
- RE_DEBUG(1,(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
- num, dat, dlen, d, s),);
- RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
-} /* end re_insert */
+ ELRE_DEBUG(1,
+ (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
+ num, dat, dlen, d, s));
+ ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
+}
/* re_delete():
@@ -311,50 +375,47 @@ re_insert(el, d, dat, dlen, s, num)
*/
private void
/*ARGSUSED*/
-re_delete(el, d, dat, dlen, num)
- EditLine *el;
- char *d;
- int dat, dlen, num;
+re_delete(EditLine *el, char *d, int dat, int dlen, int num)
{
- char *a, *b;
-
- if (num <= 0)
- return;
- if (dat + num >= dlen) {
- d[dat] = '\0';
- return;
- }
-
- RE_DEBUG(1,(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d),);
-
- /* open up the space for num chars */
- if (num > 0) {
- b = d + dat;
- a = b + num;
- while (a < &d[dlen])
- *b++ = *a++;
- d[dlen] = '\0'; /* just in case */
- }
- RE_DEBUG(1,(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d),);
-} /* end re_delete */
+ char *a, *b;
+
+ if (num <= 0)
+ return;
+ if (dat + num >= dlen) {
+ d[dat] = '\0';
+ return;
+ }
+ ELRE_DEBUG(1,
+ (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d));
+
+ /* open up the space for num chars */
+ if (num > 0) {
+ b = d + dat;
+ a = b + num;
+ while (a < &d[dlen])
+ *b++ = *a++;
+ d[dlen] = '\0'; /* just in case */
+ }
+ ELRE_DEBUG(1,
+ (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d));
+}
/* re__strncopy():
* Like strncpy without padding.
*/
private void
-re__strncopy(a, b, n)
- char *a, *b;
- size_t n;
+re__strncopy(char *a, char *b, size_t n)
{
- while (n-- && *b)
- *a++ = *b++;
-} /* end re__strncopy */
+
+ while (n-- && *b)
+ *a++ = *b++;
+}
-/* ****************************************************************
+/*****************************************************************
re_update_line() is based on finding the middle difference of each line
on the screen; vis:
@@ -376,568 +437,593 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
* going back out. This should really be calculated from the termcap
* data... For the moment, a good number for ANSI terminals.
*/
-#define MIN_END_KEEP 4
+#define MIN_END_KEEP 4
private void
-re_update_line(el, old, new, i)
- EditLine *el;
- char *old, *new;
- int i;
+re_update_line(EditLine *el, char *old, char *new, int i)
{
- char *o, *n, *p, c;
- char *ofd, *ols, *oe, *nfd, *nls, *ne;
- char *osb, *ose, *nsb, *nse;
- int fx, sx;
-
- /*
- * find first diff
- */
- for (o = old, n = new; *o && (*o == *n); o++, n++)
- continue;
- ofd = o;
- nfd = n;
-
- /*
- * Find the end of both old and new
- */
- while (*o)
- o++;
- /*
- * Remove any trailing blanks off of the end, being careful not to
- * back up past the beginning.
- */
- while (ofd < o) {
- if (o[-1] != ' ')
- break;
- o--;
- }
- oe = o;
- *oe = '\0';
-
- while (*n)
- n++;
-
- /* remove blanks from end of new */
- while (nfd < n) {
- if (n[-1] != ' ')
- break;
- n--;
- }
- ne = n;
- *ne = '\0';
-
- /*
- * if no diff, continue to next line of redraw
- */
- if (*ofd == '\0' && *nfd == '\0') {
- RE_DEBUG(1,(__F, "no difference.\r\n"),);
- return;
- }
-
- /*
- * find last same pointer
- */
- while ((o > ofd) && (n > nfd) && (*--o == *--n))
- continue;
- ols = ++o;
- nls = ++n;
-
- /*
- * find same begining and same end
- */
- osb = ols;
- nsb = nls;
- ose = ols;
- nse = nls;
-
- /*
- * case 1: insert: scan from nfd to nls looking for *ofd
- */
- if (*ofd) {
- for (c = *ofd, n = nfd; n < nls; n++) {
- if (c == *n) {
- for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++)
- continue;
- /*
- * if the new match is longer and it's worth keeping, then we
- * take it
- */
- if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) {
- nsb = n;
- nse = p;
- osb = ofd;
- ose = o;
- }
- }
- }
- }
-
- /*
- * case 2: delete: scan from ofd to ols looking for *nfd
- */
- if (*nfd) {
- for (c = *nfd, o = ofd; o < ols; o++) {
- if (c == *o) {
- for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++)
- continue;
- /*
- * if the new match is longer and it's worth keeping, then we
- * take it
- */
- if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) {
- nsb = nfd;
- nse = n;
- osb = o;
- ose = p;
- }
- }
- }
- }
-
- /*
- * Pragmatics I: If old trailing whitespace or not enough characters to
- * save to be worth it, then don't save the last same info.
- */
- if ((oe - ols) < MIN_END_KEEP) {
- ols = oe;
- nls = ne;
- }
-
- /*
- * Pragmatics II: if the terminal isn't smart enough, make the data dumber
- * so the smart update doesn't try anything fancy
- */
-
- /*
- * fx is the number of characters we need to insert/delete: in the
- * beginning to bring the two same begins together
- */
- fx = (nsb - nfd) - (osb - ofd);
- /*
- * sx is the number of characters we need to insert/delete: in the end to
- * bring the two same last parts together
- */
- sx = (nls - nse) - (ols - ose);
-
- if (!EL_CAN_INSERT) {
- if (fx > 0) {
- osb = ols;
- ose = ols;
- nsb = nls;
- nse = nls;
- }
- if (sx > 0) {
- ols = oe;
- nls = ne;
- }
- if ((ols - ofd) < (nls - nfd)) {
- ols = oe;
- nls = ne;
- }
- }
- if (!EL_CAN_DELETE) {
- if (fx < 0) {
- osb = ols;
- ose = ols;
- nsb = nls;
- nse = nls;
+ char *o, *n, *p, c;
+ char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ char *osb, *ose, *nsb, *nse;
+ int fx, sx;
+
+ /*
+ * find first diff
+ */
+ for (o = old, n = new; *o && (*o == *n); o++, n++)
+ continue;
+ ofd = o;
+ nfd = n;
+
+ /*
+ * Find the end of both old and new
+ */
+ while (*o)
+ o++;
+ /*
+ * Remove any trailing blanks off of the end, being careful not to
+ * back up past the beginning.
+ */
+ while (ofd < o) {
+ if (o[-1] != ' ')
+ break;
+ o--;
}
- if (sx < 0) {
- ols = oe;
- nls = ne;
+ oe = o;
+ *oe = '\0';
+
+ while (*n)
+ n++;
+
+ /* remove blanks from end of new */
+ while (nfd < n) {
+ if (n[-1] != ' ')
+ break;
+ n--;
}
- if ((ols - ofd) > (nls - nfd)) {
- ols = oe;
- nls = ne;
+ ne = n;
+ *ne = '\0';
+
+ /*
+ * if no diff, continue to next line of redraw
+ */
+ if (*ofd == '\0' && *nfd == '\0') {
+ ELRE_DEBUG(1, (__F, "no difference.\r\n"));
+ return;
}
- }
-
- /*
- * Pragmatics III: make sure the middle shifted pointers are correct if
- * they don't point to anything (we may have moved ols or nls).
- */
- /* if the change isn't worth it, don't bother */
- /* was: if (osb == ose) */
- if ((ose - osb) < MIN_END_KEEP) {
+ /*
+ * find last same pointer
+ */
+ while ((o > ofd) && (n > nfd) && (*--o == *--n))
+ continue;
+ ols = ++o;
+ nls = ++n;
+
+ /*
+ * find same begining and same end
+ */
osb = ols;
- ose = ols;
nsb = nls;
+ ose = ols;
nse = nls;
- }
-
- /*
- * Now that we are done with pragmatics we recompute fx, sx
- */
- fx = (nsb - nfd) - (osb - ofd);
- sx = (nls - nse) - (ols - ose);
-
- RE_DEBUG(1,(__F, "\n"),);
- RE_DEBUG(1,(__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
- ofd - old, osb - old, ose - old, ols - old, oe - old),);
- RE_DEBUG(1,(__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
- nfd - new, nsb - new, nse - new, nls - new, ne - new),);
- RE_DEBUG(1,(__F,
- "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"),);
- RE_DEBUG(1,(__F,
- "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"),);
-#ifdef DEBUG_REFRESH
- re_printstr(el, "old- oe", old, oe);
- re_printstr(el, "new- ne", new, ne);
- re_printstr(el, "old-ofd", old, ofd);
- re_printstr(el, "new-nfd", new, nfd);
- re_printstr(el, "ofd-osb", ofd, osb);
- re_printstr(el, "nfd-nsb", nfd, nsb);
- re_printstr(el, "osb-ose", osb, ose);
- re_printstr(el, "nsb-nse", nsb, nse);
- re_printstr(el, "ose-ols", ose, ols);
- re_printstr(el, "nse-nls", nse, nls);
- re_printstr(el, "ols- oe", ols, oe);
- re_printstr(el, "nls- ne", nls, ne);
-#endif /* DEBUG_REFRESH */
- /*
- * el_cursor.v to this line i MUST be in this routine so that if we
- * don't have to change the line, we don't move to it. el_cursor.h to first
- * diff char
- */
- term_move_to_line(el, i);
-
- /*
- * at this point we have something like this:
- *
- * /old /ofd /osb /ose /ols /oe
- * v.....................v v..................v v........v
- * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
- * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
- * ^.....................^ ^..................^ ^........^
- * \new \nfd \nsb \nse \nls \ne
- *
- * fx is the difference in length between the the chars between nfd and
- * nsb, and the chars between ofd and osb, and is thus the number of
- * characters to delete if < 0 (new is shorter than old, as above),
- * or insert (new is longer than short).
- *
- * sx is the same for the second differences.
- */
-
- /*
- * if we have a net insert on the first difference, AND inserting the net
- * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character
- * (which is ne if nls != ne, otherwise is nse) off the edge of the screen
- * (el->el_term.t_size.h) else we do the deletes first so that we keep everything we need
- * to.
- */
-
- /*
- * if the last same is the same like the end, there is no last same part,
- * otherwise we want to keep the last same part set p to the last useful
- * old character
- */
- p = (ols != oe) ? oe : ose;
-
- /*
- * if (There is a diffence in the beginning) && (we need to insert
- * characters) && (the number of characters to insert is less than the term
- * width) We need to do an insert! else if (we need to delete characters)
- * We need to delete characters! else No insert or delete
- */
- if ((nsb != nfd) && fx > 0 && ((p - old) + fx <= el->el_term.t_size.h)) {
- RE_DEBUG(1,(__F, "first diff insert at %d...\r\n", nfd - new),);
- /*
- * Move to the first char to insert, where the first diff is.
- */
- term_move_to_char(el, nfd - new);
/*
- * Check if we have stuff to keep at end
- */
- if (nsb != ne) {
- RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
- /*
- * insert fx chars of new starting at nfd
- */
- if (fx > 0) {
- RE_DEBUG(!EL_CAN_INSERT,
- (__F, "ERROR: cannot insert in early first diff\n"),);
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
- }
- /*
- * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
- */
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
+ * case 1: insert: scan from nfd to nls looking for *ofd
+ */
+ if (*ofd) {
+ for (c = *ofd, n = nfd; n < nls; n++) {
+ if (c == *n) {
+ for (o = ofd, p = n;
+ p < nls && o < ols && *o == *p;
+ o++, p++)
+ continue;
+ /*
+ * if the new match is longer and it's worth
+ * keeping, then we take it
+ */
+ if (((nse - nsb) < (p - n)) &&
+ (2 * (p - n) > n - nfd)) {
+ nsb = n;
+ nse = p;
+ osb = ofd;
+ ose = o;
+ }
+ }
+ }
}
- else {
- RE_DEBUG(1,(__F, "without anything to save\r\n"),);
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (nsb - nfd));
- /*
- * Done
- */
- return;
+ /*
+ * case 2: delete: scan from ofd to ols looking for *nfd
+ */
+ if (*nfd) {
+ for (c = *nfd, o = ofd; o < ols; o++) {
+ if (c == *o) {
+ for (n = nfd, p = o;
+ p < ols && n < nls && *p == *n;
+ p++, n++)
+ continue;
+ /*
+ * if the new match is longer and it's worth
+ * keeping, then we take it
+ */
+ if (((ose - osb) < (p - o)) &&
+ (2 * (p - o) > o - ofd)) {
+ nsb = nfd;
+ nse = n;
+ osb = o;
+ ose = p;
+ }
+ }
+ }
}
- }
- else if (fx < 0) {
- RE_DEBUG(1,(__F, "first diff delete at %d...\r\n", ofd - old),);
/*
- * move to the first char to delete where the first diff is
- */
- term_move_to_char(el, ofd - old);
+ * Pragmatics I: If old trailing whitespace or not enough characters to
+ * save to be worth it, then don't save the last same info.
+ */
+ if ((oe - ols) < MIN_END_KEEP) {
+ ols = oe;
+ nls = ne;
+ }
/*
- * Check if we have stuff to save
- */
- if (osb != oe) {
- RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
- /*
- * fx is less than zero *always* here but we check for code
- * symmetry
- */
- if (fx < 0) {
- RE_DEBUG(!EL_CAN_DELETE,
- (__F, "ERROR: cannot delete in first diff\n"),);
- term_deletechars(el, -fx);
- re_delete(el, old, ofd - old, el->el_term.t_size.h, -fx);
- }
- /*
- * write (nsb-nfd) chars of new starting at nfd
- */
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (nsb - nfd));
+ * Pragmatics II: if the terminal isn't smart enough, make the data
+ * dumber so the smart update doesn't try anything fancy
+ */
+ /*
+ * fx is the number of characters we need to insert/delete: in the
+ * beginning to bring the two same begins together
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ /*
+ * sx is the number of characters we need to insert/delete: in the
+ * end to bring the two same last parts together
+ */
+ sx = (nls - nse) - (ols - ose);
+
+ if (!EL_CAN_INSERT) {
+ if (fx > 0) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
+ }
+ if (sx > 0) {
+ ols = oe;
+ nls = ne;
+ }
+ if ((ols - ofd) < (nls - nfd)) {
+ ols = oe;
+ nls = ne;
+ }
+ }
+ if (!EL_CAN_DELETE) {
+ if (fx < 0) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
+ }
+ if (sx < 0) {
+ ols = oe;
+ nls = ne;
+ }
+ if ((ols - ofd) > (nls - nfd)) {
+ ols = oe;
+ nls = ne;
+ }
}
- else {
- RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
- /*
- * write (nsb-nfd) chars of new starting at nfd
- */
- term_overwrite(el, nfd, (nsb - nfd));
- RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
- term_clear_EOL(el, (oe - old) - (ne - new));
- /*
- * Done
- */
- return;
+ /*
+ * Pragmatics III: make sure the middle shifted pointers are correct if
+ * they don't point to anything (we may have moved ols or nls).
+ */
+ /* if the change isn't worth it, don't bother */
+ /* was: if (osb == ose) */
+ if ((ose - osb) < MIN_END_KEEP) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
}
- }
- else
- fx = 0;
+ /*
+ * Now that we are done with pragmatics we recompute fx, sx
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ sx = (nls - nse) - (ols - ose);
+
+ ELRE_DEBUG(1, (__F, "\n"));
+ ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
+ ofd - old, osb - old, ose - old, ols - old, oe - old));
+ ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
+ nfd - new, nsb - new, nse - new, nls - new, ne - new));
+ ELRE_DEBUG(1, (__F,
+ "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
+ ELRE_DEBUG(1, (__F,
+ "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"));
+#ifdef DEBUG_REFRESH
+ re_printstr(el, "old- oe", old, oe);
+ re_printstr(el, "new- ne", new, ne);
+ re_printstr(el, "old-ofd", old, ofd);
+ re_printstr(el, "new-nfd", new, nfd);
+ re_printstr(el, "ofd-osb", ofd, osb);
+ re_printstr(el, "nfd-nsb", nfd, nsb);
+ re_printstr(el, "osb-ose", osb, ose);
+ re_printstr(el, "nsb-nse", nsb, nse);
+ re_printstr(el, "ose-ols", ose, ols);
+ re_printstr(el, "nse-nls", nse, nls);
+ re_printstr(el, "ols- oe", ols, oe);
+ re_printstr(el, "nls- ne", nls, ne);
+#endif /* DEBUG_REFRESH */
- if (sx < 0) {
- RE_DEBUG(1,(__F, "second diff delete at %d...\r\n", (ose - old) + fx),);
/*
- * Check if we have stuff to delete
- */
+ * el_cursor.v to this line i MUST be in this routine so that if we
+ * don't have to change the line, we don't move to it. el_cursor.h to
+ * first diff char
+ */
+ term_move_to_line(el, i);
+
/*
- * fx is the number of characters inserted (+) or deleted (-)
- */
+ * at this point we have something like this:
+ *
+ * /old /ofd /osb /ose /ols /oe
+ * v.....................v v..................v v........v
+ * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
+ * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
+ * ^.....................^ ^..................^ ^........^
+ * \new \nfd \nsb \nse \nls \ne
+ *
+ * fx is the difference in length between the chars between nfd and
+ * nsb, and the chars between ofd and osb, and is thus the number of
+ * characters to delete if < 0 (new is shorter than old, as above),
+ * or insert (new is longer than short).
+ *
+ * sx is the same for the second differences.
+ */
- term_move_to_char(el, (ose - old) + fx);
/*
- * Check if we have stuff to save
- */
- if (ols != oe) {
- RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
- /*
- * Again a duplicate test.
- */
- if (sx < 0) {
- RE_DEBUG(!EL_CAN_DELETE,
- (__F, "ERROR: cannot delete in second diff\n"),);
- term_deletechars(el, -sx);
- }
-
- /*
- * write (nls-nse) chars of new starting at nse
- */
- term_overwrite(el, nse, (nls - nse));
- }
- else {
- RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
- term_overwrite(el, nse, (nls - nse));
- RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
- term_clear_EOL(el, (oe - old) - (ne - new));
- }
- }
+ * if we have a net insert on the first difference, AND inserting the
+ * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
+ * character (which is ne if nls != ne, otherwise is nse) off the edge
+ * of the screen (el->el_term.t_size.h) else we do the deletes first
+ * so that we keep everything we need to.
+ */
- /*
- * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
- */
- if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
- RE_DEBUG(1,(__F, "late first diff insert at %d...\r\n", nfd - new),);
+ /*
+ * if the last same is the same like the end, there is no last same
+ * part, otherwise we want to keep the last same part set p to the
+ * last useful old character
+ */
+ p = (ols != oe) ? oe : ose;
- term_move_to_char(el, nfd - new);
/*
- * Check if we have stuff to keep at the end
- */
- if (nsb != ne) {
- RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
- /*
- * We have to recalculate fx here because we set it
- * to zero above as a flag saying that we hadn't done
- * an early first insert.
- */
- fx = (nsb - nfd) - (osb - ofd);
- if (fx > 0) {
+ * if (There is a diffence in the beginning) && (we need to insert
+ * characters) && (the number of characters to insert is less than
+ * the term width)
+ * We need to do an insert!
+ * else if (we need to delete characters)
+ * We need to delete characters!
+ * else
+ * No insert or delete
+ */
+ if ((nsb != nfd) && fx > 0 &&
+ ((p - old) + fx <= el->el_term.t_size.h)) {
+ ELRE_DEBUG(1,
+ (__F, "first diff insert at %d...\r\n", nfd - new));
/*
- * insert fx chars of new starting at nfd
+ * Move to the first char to insert, where the first diff is.
*/
- RE_DEBUG(!EL_CAN_INSERT,
- (__F, "ERROR: cannot insert in late first diff\n"),);
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
- }
-
- /*
- * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
- */
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
- }
- else {
- RE_DEBUG(1,(__F, "without anything to save\r\n"),);
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (nsb - nfd));
+ term_move_to_char(el, nfd - new);
+ /*
+ * Check if we have stuff to keep at end
+ */
+ if (nsb != ne) {
+ ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
+ /*
+ * insert fx chars of new starting at nfd
+ */
+ if (fx > 0) {
+ ELRE_DEBUG(!EL_CAN_INSERT, (__F,
+ "ERROR: cannot insert in early first diff\n"));
+ term_insertwrite(el, nfd, fx);
+ re_insert(el, old, ofd - old,
+ el->el_term.t_size.h, nfd, fx);
+ }
+ /*
+ * write (nsb-nfd) - fx chars of new starting at
+ * (nfd + fx)
+ */
+ term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
+ re__strncopy(ofd + fx, nfd + fx,
+ (size_t) ((nsb - nfd) - fx));
+ } else {
+ ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+ /*
+ * Done
+ */
+ return;
+ }
+ } else if (fx < 0) {
+ ELRE_DEBUG(1,
+ (__F, "first diff delete at %d...\r\n", ofd - old));
+ /*
+ * move to the first char to delete where the first diff is
+ */
+ term_move_to_char(el, ofd - old);
+ /*
+ * Check if we have stuff to save
+ */
+ if (osb != oe) {
+ ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
+ /*
+ * fx is less than zero *always* here but we check
+ * for code symmetry
+ */
+ if (fx < 0) {
+ ELRE_DEBUG(!EL_CAN_DELETE, (__F,
+ "ERROR: cannot delete in first diff\n"));
+ term_deletechars(el, -fx);
+ re_delete(el, old, ofd - old,
+ el->el_term.t_size.h, -fx);
+ }
+ /*
+ * write (nsb-nfd) chars of new starting at nfd
+ */
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+
+ } else {
+ ELRE_DEBUG(1, (__F,
+ "but with nothing left to save\r\n"));
+ /*
+ * write (nsb-nfd) chars of new starting at nfd
+ */
+ term_overwrite(el, nfd, (nsb - nfd));
+ ELRE_DEBUG(1, (__F,
+ "cleareol %d\n", (oe - old) - (ne - new)));
+ term_clear_EOL(el, (oe - old) - (ne - new));
+ /*
+ * Done
+ */
+ return;
+ }
+ } else
+ fx = 0;
+
+ if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) {
+ ELRE_DEBUG(1, (__F,
+ "second diff delete at %d...\r\n", (ose - old) + fx));
+ /*
+ * Check if we have stuff to delete
+ */
+ /*
+ * fx is the number of characters inserted (+) or deleted (-)
+ */
+
+ term_move_to_char(el, (ose - old) + fx);
+ /*
+ * Check if we have stuff to save
+ */
+ if (ols != oe) {
+ ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
+ /*
+ * Again a duplicate test.
+ */
+ if (sx < 0) {
+ ELRE_DEBUG(!EL_CAN_DELETE, (__F,
+ "ERROR: cannot delete in second diff\n"));
+ term_deletechars(el, -sx);
+ }
+ /*
+ * write (nls-nse) chars of new starting at nse
+ */
+ term_overwrite(el, nse, (nls - nse));
+ } else {
+ ELRE_DEBUG(1, (__F,
+ "but with nothing left to save\r\n"));
+ term_overwrite(el, nse, (nls - nse));
+ ELRE_DEBUG(1, (__F,
+ "cleareol %d\n", (oe - old) - (ne - new)));
+ if ((oe - old) - (ne - new) != 0)
+ term_clear_EOL(el, (oe - old) - (ne - new));
+ }
}
- }
-
- /*
- * line is now NEW up to nse
- */
- if (sx >= 0) {
- RE_DEBUG(1,(__F, "second diff insert at %d...\r\n", nse - new),);
- term_move_to_char(el, nse - new);
- if (ols != oe) {
- RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
- if (sx > 0) {
- /* insert sx chars of new starting at nse */
- RE_DEBUG(!EL_CAN_INSERT,
- (__F, "ERROR: cannot insert in second diff\n"),);
- term_insertwrite(el, nse, sx);
- }
-
- /*
- * write (nls-nse) - sx chars of new starting at (nse + sx)
- */
- term_overwrite(el, nse + sx, (nls - nse) - sx);
+ /*
+ * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
+ */
+ if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
+ ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
+ nfd - new));
+
+ term_move_to_char(el, nfd - new);
+ /*
+ * Check if we have stuff to keep at the end
+ */
+ if (nsb != ne) {
+ ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
+ /*
+ * We have to recalculate fx here because we set it
+ * to zero above as a flag saying that we hadn't done
+ * an early first insert.
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ if (fx > 0) {
+ /*
+ * insert fx chars of new starting at nfd
+ */
+ ELRE_DEBUG(!EL_CAN_INSERT, (__F,
+ "ERROR: cannot insert in late first diff\n"));
+ term_insertwrite(el, nfd, fx);
+ re_insert(el, old, ofd - old,
+ el->el_term.t_size.h, nfd, fx);
+ }
+ /*
+ * write (nsb-nfd) - fx chars of new starting at
+ * (nfd + fx)
+ */
+ term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
+ re__strncopy(ofd + fx, nfd + fx,
+ (size_t) ((nsb - nfd) - fx));
+ } else {
+ ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+ }
}
- else {
- RE_DEBUG(1,(__F, "without anything to save\r\n"),);
- term_overwrite(el, nse, (nls - nse));
-
- /*
- * No need to do a clear-to-end here because we were doing
- * a second insert, so we will have over written all of the
- * old string.
- */
+ /*
+ * line is now NEW up to nse
+ */
+ if (sx >= 0) {
+ ELRE_DEBUG(1, (__F,
+ "second diff insert at %d...\r\n", nse - new));
+ term_move_to_char(el, nse - new);
+ if (ols != oe) {
+ ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
+ if (sx > 0) {
+ /* insert sx chars of new starting at nse */
+ ELRE_DEBUG(!EL_CAN_INSERT, (__F,
+ "ERROR: cannot insert in second diff\n"));
+ term_insertwrite(el, nse, sx);
+ }
+ /*
+ * write (nls-nse) - sx chars of new starting at
+ * (nse + sx)
+ */
+ term_overwrite(el, nse + sx, (nls - nse) - sx);
+ } else {
+ ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
+ term_overwrite(el, nse, (nls - nse));
+
+ /*
+ * No need to do a clear-to-end here because we were
+ * doing a second insert, so we will have over
+ * written all of the old string.
+ */
+ }
}
- }
- RE_DEBUG(1,(__F, "done.\r\n"),);
-} /* re_update_line */
+ ELRE_DEBUG(1, (__F, "done.\r\n"));
+}
/* re__copy_and_pad():
* Copy string and pad with spaces
*/
private void
-re__copy_and_pad(dst, src, width)
- char *dst, *src;
- size_t width;
+re__copy_and_pad(char *dst, char *src, size_t width)
{
- int i;
+ int i;
- for (i = 0; i < width; i++) {
- if (*src == '\0')
- break;
- *dst++ = *src++;
- }
+ for (i = 0; i < width; i++) {
+ if (*src == '\0')
+ break;
+ *dst++ = *src++;
+ }
- while (i < width) {
- *dst++ = ' ';
- i++;
- }
- *dst = '\0';
-} /* end re__copy_and_pad */
+ for (; i < width; i++)
+ *dst++ = ' ';
+
+ *dst = '\0';
+}
/* re_refresh_cursor():
* Move to the new cursor position
*/
protected void
-re_refresh_cursor(el)
- EditLine *el;
+re_refresh_cursor(EditLine *el)
{
- char *cp;
- int c;
- int h, v, th;
-
- /* first we must find where the cursor is... */
- h = el->el_prompt.p_pos.h;
- v = el->el_prompt.p_pos.v;
- th = el->el_term.t_size.h; /* optimize for speed */
-
- /* do input buffer to el->el_line.cursor */
- for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
- c = (unsigned char)*cp;
- h++; /* all chars at least this long */
-
- if (c == '\n') { /* handle newline in data part too */
- h = 0;
- v++;
- }
- else {
- if (c == '\t') { /* if a tab, to next tab stop */
- while (h & 07) {
- h++;
- }
- }
- else if (iscntrl(c)) { /* if control char */
- h++;
- if (h > th) { /* if overflow, compensate */
- h = 1;
- v++;
+ char *cp, c;
+ int h, v, th;
+
+ /* first we must find where the cursor is... */
+ h = el->el_prompt.p_pos.h;
+ v = el->el_prompt.p_pos.v;
+ th = el->el_term.t_size.h; /* optimize for speed */
+
+ /* do input buffer to el->el_line.cursor */
+ for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
+ c = (unsigned char)*cp;
+ h++; /* all chars at least this long */
+
+ if (c == '\n') {/* handle newline in data part too */
+ h = 0;
+ v++;
+ } else {
+ if (c == '\t') { /* if a tab, to next tab stop */
+ while (h & 07) {
+ h++;
+ }
+ } else if (iscntrl((unsigned char) c)) {
+ /* if control char */
+ h++;
+ if (h > th) { /* if overflow, compensate */
+ h = 1;
+ v++;
+ }
+ } else if (!isprint((unsigned char) c)) {
+ h += 3;
+ if (h > th) { /* if overflow, compensate */
+ h = h - th;
+ v++;
+ }
+ }
}
- }
- else if (!isprint(c)) {
- h += 3;
- if (h > th) { /* if overflow, compensate */
- h = h - th;
- v++;
- }
- }
- }
- if (h >= th) { /* check, extra long tabs picked up here also */
- h = 0;
- v++;
+ if (h >= th) { /* check, extra long tabs picked up here also */
+ h = 0;
+ v++;
+ }
}
- }
- /* now go there */
- term_move_to_line(el, v);
- term_move_to_char(el, h);
- term__flush();
-} /* re_refresh_cursor */
+ /* now go there */
+ term_move_to_line(el, v);
+ term_move_to_char(el, h);
+ term__flush();
+}
/* re_fastputc():
* Add a character fast.
*/
private void
-re_fastputc(el, c)
- EditLine *el;
- int c;
+re_fastputc(EditLine *el, int c)
{
- term__putc(c);
- el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
- if (el->el_cursor.h >= el->el_term.t_size.h) {
- /* if we must overflow */
- el->el_cursor.h = 0;
- el->el_cursor.v++;
- el->el_refresh.r_oldcv++;
- term__putc('\r');
- term__putc('\n');
- }
-} /* end re_fastputc */
+
+ term__putc(c);
+ el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
+ if (el->el_cursor.h >= el->el_term.t_size.h) {
+ /* if we must overflow */
+ el->el_cursor.h = 0;
+
+ /*
+ * If we would overflow (input is longer than terminal size),
+ * emulate scroll by dropping first line and shuffling the rest.
+ * We do this via pointer shuffling - it's safe in this case
+ * and we avoid memcpy().
+ */
+ if (el->el_cursor.v + 1 >= el->el_term.t_size.v) {
+ int i, lins = el->el_term.t_size.v;
+ char *firstline = el->el_display[0];
+
+ for(i=1; i < lins; i++)
+ el->el_display[i-1] = el->el_display[i];
+
+ re__copy_and_pad(firstline, "", 0);
+ el->el_display[i-1] = firstline;
+ } else {
+ el->el_cursor.v++;
+ el->el_refresh.r_oldcv++;
+ }
+ if (EL_HAS_AUTO_MARGINS) {
+ if (EL_HAS_MAGIC_MARGINS) {
+ term__putc(' ');
+ term__putc('\b');
+ }
+ } else {
+ term__putc('\r');
+ term__putc('\n');
+ }
+ }
+}
/* re_fastaddc():
@@ -945,73 +1031,75 @@ re_fastputc(el, c)
* Assumes that screen cursor == real cursor
*/
protected void
-re_fastaddc(el)
- EditLine *el;
+re_fastaddc(EditLine *el)
{
- int c;
-
- c = (unsigned char)el->el_line.cursor[-1];
-
- if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
- re_refresh(el); /* too hard to handle */
- return;
- } /* else (only do at end of line, no TAB) */
-
- if (iscntrl(c)) { /* if control char, do caret */
- char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
- re_fastputc(el, '^');
- re_fastputc(el, mc);
- }
- else if (isprint(c)) { /* normal char */
- re_fastputc(el, c);
- }
- else {
- re_fastputc(el, '\\');
- re_fastputc(el, ((c >> 6) & 7) + '0');
- re_fastputc(el, ((c >> 3) & 7) + '0');
- re_fastputc(el, (c & 7) + '0');
- }
- term__flush();
-} /* end re_fastaddc */
+ char c;
+ int rhdiff;
+
+ c = (unsigned char)el->el_line.cursor[-1];
+
+ if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
+ re_refresh(el); /* too hard to handle */
+ return;
+ }
+ rhdiff = el->el_term.t_size.h - el->el_cursor.h -
+ el->el_rprompt.p_pos.h;
+ if (el->el_rprompt.p_pos.h && rhdiff < 3) {
+ re_refresh(el); /* clear out rprompt if less than 1 char gap */
+ return;
+ } /* else (only do at end of line, no TAB) */
+ if (iscntrl((unsigned char) c)) { /* if control char, do caret */
+ char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
+ re_fastputc(el, '^');
+ re_fastputc(el, mc);
+ } else if (isprint((unsigned char) c)) { /* normal char */
+ re_fastputc(el, c);
+ } else {
+ re_fastputc(el, '\\');
+ re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0'));
+ re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0'));
+ re_fastputc(el, (c & 7) + '0');
+ }
+ term__flush();
+}
/* re_clear_display():
* clear the screen buffers so that new new prompt starts fresh.
*/
protected void
-re_clear_display(el)
- EditLine *el;
+re_clear_display(EditLine *el)
{
- int i;
+ int i;
- el->el_cursor.v = 0;
- el->el_cursor.h = 0;
- for (i = 0; i < el->el_term.t_size.v; i++)
- el->el_display[i][0] = '\0';
- el->el_refresh.r_oldcv = 0;
-} /* end re_clear_display */
+ el->el_cursor.v = 0;
+ el->el_cursor.h = 0;
+ for (i = 0; i < el->el_term.t_size.v; i++)
+ el->el_display[i][0] = '\0';
+ el->el_refresh.r_oldcv = 0;
+}
/* re_clear_lines():
* Make sure all lines are *really* blank
*/
protected void
-re_clear_lines(el)
- EditLine *el;
+re_clear_lines(EditLine *el)
{
- if (EL_CAN_CEOL) {
- int i;
- term_move_to_char(el, 0);
- for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
- /* for each line on the screen */
- term_move_to_line(el, i);
- term_clear_EOL(el, el->el_term.t_size.h);
+
+ if (EL_CAN_CEOL) {
+ int i;
+ term_move_to_char(el, 0);
+ for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
+ /* for each line on the screen */
+ term_move_to_line(el, i);
+ term_clear_EOL(el, el->el_term.t_size.h);
+ }
+ term_move_to_line(el, 0);
+ } else {
+ term_move_to_line(el, el->el_refresh.r_oldcv);
+ /* go to last line */
+ term__putc('\r'); /* go to BOL */
+ term__putc('\n'); /* go to new line */
}
- term_move_to_line(el, 0);
- }
- else {
- term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */
- term__putc('\r'); /* go to BOL */
- term__putc('\n'); /* go to new line */
- }
-} /* end re_clear_lines */
+}
OpenPOWER on IntegriCloud