112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*	$NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $	*/
212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*-
412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1992, 1993
512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	The Regents of the University of California.  All rights reserved.
612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * This code is derived from software contributed to Berkeley by
812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Christos Zoulas of Cornell University.
912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without
1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions
1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met:
1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright
1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer.
1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright
1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer in the
1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    documentation and/or other materials provided with the distribution.
1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors
1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    may be used to endorse or promote products derived from this software
2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    without specific prior written permission.
2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE.
3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h"
3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID)
3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0
3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 6/4/93";
3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else
4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $");
4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */
4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*
4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * refresh.c: Lower level screen refreshing functions
4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdio.h>
4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <ctype.h>
4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <unistd.h>
5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <string.h>
5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h"
5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_nextline(EditLine *);
5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_addc(EditLine *, Int);
5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_update_line(EditLine *, Char *, Char *, int);
5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_insert (EditLine *, Char *, int, int, Char *, int);
5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_delete(EditLine *, Char *, int, int, int);
5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_fastputc(EditLine *, Int);
6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_clear_eol(EditLine *, int, int, int);
6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re__strncopy(Char *, Char *, size_t);
6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re__copy_and_pad(Char *, const Char *, size_t);
6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_REFRESH
6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	re_printstr(EditLine *, const char *, char *, char *);
6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	__F el->el_errfile
6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	ELRE_ASSERT(a, b, c)	do 				\
6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    if (/*CONSTCOND*/ a) {	\
6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					(void) fprintf b;	\
7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					c;			\
7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    }				\
7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				while (/*CONSTCOND*/0)
7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	ELRE_DEBUG(a, b)	ELRE_ASSERT(a,b,;)
7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_printstr():
7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Print a string on the debugging pty
7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_printstr(EditLine *el, const char *str, char *f, char *t)
8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "%s:\"", str));
8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (f < t)
8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1, (__F, "%c", *f++ & 0177));
8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "\"\r\n"));
8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else
8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	ELRE_ASSERT(a, b, c)
8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	ELRE_DEBUG(a, b)
9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_nextline():
9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Move to the next line or scroll
9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_nextline(EditLine *el)
9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.h = 0;	/* reset it. */
9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * If we would overflow (input is longer than terminal size),
10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * emulate scroll by dropping first line and shuffling the rest.
10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * We do this via pointer shuffling - it's safe in this case
10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * and we avoid memcpy().
10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 */
10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int i, lins = el->el_terminal.t_size.v;
10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char *firstline = el->el_vdisplay[0];
10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for(i = 1; i < lins; i++)
11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_vdisplay[i - 1] = el->el_vdisplay[i];
11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		firstline[0] = '\0';		/* empty the string */
11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_vdisplay[i - 1] = firstline;
11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_refresh.r_cursor.v++;
11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    abort());
12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_addc():
12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Draw c, expanding tabs, control chars etc.
12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_addc(EditLine *el, Int c)
12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (ct_chr_class((Char)c)) {
13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_TAB:        /* expand the tab */
13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (;;) {
13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_putc(el, ' ', 1);
13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((el->el_refresh.r_cursor.h & 07) == 0)
13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;			/* go until tab stop */
13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_NL: {
13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int oldv = el->el_refresh.r_cursor.v;
14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_putc(el, '\0', 0);			/* assure end of line */
14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (oldv == el->el_refresh.r_cursor.v)	/* XXX */
14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_nextline(el);
14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_PRINT:
14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_putc(el, c, 1);
14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	default: {
14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char visbuf[VISUAL_WIDTH_MAX];
15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ssize_t i, n =
15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = 0; n-- > 0; ++i)
15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    re_putc(el, visbuf[i], 1);
15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_putc():
16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Draw the character given
16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_putc(EditLine *el, Int c, int shift)
16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i, w = Width(c);
16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));
16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    re_putc(el, ' ', 1);
17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_vdisplay[el->el_refresh.r_cursor.v]
17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    [el->el_refresh.r_cursor.h] = c;
17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* assumes !shift is only used for single-column chars */
17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	i = w;
17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (--i > 0)
17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_vdisplay[el->el_refresh.r_cursor.v]
17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    [el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!shift)
18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.h += w;	/* advance to next place */
18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* assure end of line */
18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    = '\0';
18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_nextline(el);
18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_refresh():
19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	draws the new virtual screen image from the current input
19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *  	line, then goes line-by-line changing the real image to the new
19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	virtual image. The routine to re-draw a line can be replaced
19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	easily in hopes of a smarter one being placed there.
19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_refresh(EditLine *el)
20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i, rhdiff;
20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *cp, *st;
20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	coord_t cur;
20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef notyet
20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t termsz;
20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n",
21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_line.buffer));
21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* reset the Drawing cursor */
21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.h = 0;
21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.v = 0;
21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* temporarily draw rprompt to calculate its size */
21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	prompt_print(el, EL_RPROMPT);
21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* reset the Drawing cursor */
22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.h = 0;
22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_cursor.v = 0;
22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_line.cursor >= el->el_line.lastchar) {
22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (el->el_map.current == el->el_map.alt
22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    && el->el_line.lastchar != el->el_line.buffer)
22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_line.cursor = el->el_line.lastchar - 1;
22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else
22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_line.cursor = el->el_line.lastchar;
22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	cur.h = -1;		/* set flag in case I'm not set */
23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	cur.v = 0;
23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	prompt_print(el, EL_PROMPT);
23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* draw the current input buffer */
23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if notyet
23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_line.lastchar - el->el_line.buffer > termsz) {
24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * If line is longer than terminal, process only part
24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * of line which would influence display.
24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		st = el->el_line.lastchar - rem
24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					* el->el_terminal.t_size.v));
24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		st = el->el_line.buffer;
25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (cp = st; cp < el->el_line.lastchar; cp++) {
25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (cp == el->el_line.cursor) {
25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        int w = Width(*cp);
25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/* save for later */
25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			cur.h = el->el_refresh.r_cursor.h;
25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			cur.v = el->el_refresh.r_cursor.v;
25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        /* handle being at a linebroken doublewidth char */
26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        if (w > 1 && el->el_refresh.r_cursor.h + w >
26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    el->el_terminal.t_size.h) {
26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				cur.h = 0;
26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				cur.v++;
26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        }
26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_addc(el, *cp);
26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (cur.h == -1) {	/* if I haven't been set yet, I'm at the end */
27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		cur.h = el->el_refresh.r_cursor.h;
27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		cur.v = el->el_refresh.r_cursor.v;
27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_rprompt.p_pos.h;
27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    !el->el_refresh.r_cursor.v && rhdiff > 1) {
27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * have a right-hand side prompt that will fit
27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * on the end of the first line with at least
28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * one character gap to the input buffer.
28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (--rhdiff > 0)	/* pad out with spaces */
28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_putc(el, ' ', 1);
28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		prompt_print(el, EL_RPROMPT);
28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
28612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_rprompt.p_pos.h = 0;	/* flag "not using rprompt" */
28712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_rprompt.p_pos.v = 0;
28812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
28912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_putc(el, '\0', 0);	/* make line ended with NUL, no cursor shift */
29112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
29312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
29512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
29612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
29712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0])));
29812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
30012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i <= el->el_refresh.r_newcv; i++) {
30112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
30212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
30312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
30412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
30512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Copy the new line to be the current one, and pad out with
30612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * spaces to the full width of the terminal so that if we try
30712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * moving the cursor by writing the character that is at the
30812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * end of the screen line, it won't be a NUL or some old
30912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * leftover stuff.
31012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
31112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
31212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    (size_t) el->el_terminal.t_size.h);
31312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
31412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
31512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
31612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));
31712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
31812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
31912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (; i <= el->el_refresh.r_oldcv; i++) {
32012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_move_to_line(el, i);
32112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_move_to_char(el, 0);
32212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        /* This Strlen should be safe even with MB_FILL_CHARs */
32312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
32412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_REFRESH
32512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, "C\b", (size_t)2);
32612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_REFRESH */
32712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_display[i][0] = '\0';
32812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
32912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
33012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
33112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
33212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
33312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
33412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    cur.h, cur.v));
33512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_line(el, cur.v);	/* go to where the cursor is */
33612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_char(el, cur.h);
33712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
33812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
33912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_goto_bottom():
34112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	 used to go to last used screen line
34212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
34312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
34412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_goto_bottom(EditLine *el)
34512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
34612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_line(el, el->el_refresh.r_oldcv);
34812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__putc(el, '\n');
34912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_clear_display(el);
35012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__flush(el);
35112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
35212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
35312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
35412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_insert():
35512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	insert num characters of s into d (in front of the character)
35612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	at dat, maximum length of d is dlen
35712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
35812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
35912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
36012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_insert(EditLine *el __attribute__((__unused__)),
36112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    Char *d, int dat, int dlen, Char *s, int num)
36212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
36312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *a, *b;
36412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
36512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num <= 0)
36612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
36712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num > dlen - dat)
36812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		num = dlen - dat;
36912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
37012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1,
37112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
37212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    num, dat, dlen, ct_encode_string(d)));
37312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
37412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
37512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* open up the space for num chars */
37612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num > 0) {
37712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		b = d + dlen - 1;
37812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		a = b - num;
37912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (a >= &d[dat])
38012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*b-- = *a--;
38112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		d[dlen] = '\0';	/* just in case */
38212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
38312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
38412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
38512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
38612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		num, dat, dlen, ct_encode_string(d)));
38712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
38812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
38912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* copy the characters */
39012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (a = d + dat; (a < d + dlen) && (num > 0); num--)
39112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*a++ = *s++;
39212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
39312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef notyet
39412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala        /* ct_encode_string() uses a static buffer, so we can't conveniently
39512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * encode both d & s here */
39612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1,
39712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
39812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    num, dat, dlen, d, s));
39912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
40012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
40112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
40212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_delete():
40512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	delete num characters d at dat, maximum length of d is dlen
40612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
40712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
40812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
40912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_delete(EditLine *el __attribute__((__unused__)),
41012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    Char *d, int dat, int dlen, int num)
41112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
41212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *a, *b;
41312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
41412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num <= 0)
41512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
41612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (dat + num >= dlen) {
41712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		d[dat] = '\0';
41812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
41912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
42012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1,
42112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
42212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    num, dat, dlen, ct_encode_string(d)));
42312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
42412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* open up the space for num chars */
42512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num > 0) {
42612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		b = d + dat;
42712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		a = b + num;
42812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (a < &d[dlen])
42912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*b++ = *a++;
43012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		d[dlen] = '\0';	/* just in case */
43112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
43212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1,
43312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
43412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    num, dat, dlen, ct_encode_string(d)));
43512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
43612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
43712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
43812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re__strncopy():
43912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Like strncpy without padding.
44012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
44112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
44212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare__strncopy(Char *a, Char *b, size_t n)
44312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
44412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
44512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (n-- && *b)
44612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*a++ = *b++;
44712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
44812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
44912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_clear_eol():
45012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Find the number of characters we need to clear till the end of line
45112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	in order to make sure that we have cleared the previous contents of
45212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	the line. fx and sx is the number of characters inserted or deleted
45312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	in the first or second diff, diff is the difference between the
45412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 	number of characters between the new and old line.
45512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
45612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
45712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_clear_eol(EditLine *el, int fx, int sx, int diff)
45812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
45912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
46012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n",
46112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sx, fx, diff));
46212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
46312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (fx < 0)
46412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		fx = -fx;
46512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (sx < 0)
46612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		sx = -sx;
46712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (fx > diff)
46812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		diff = fx;
46912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (sx > diff)
47012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		diff = sx;
47112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
47212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
47312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_clear_EOL(el, diff);
47412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
47512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
47612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*****************************************************************
47712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    re_update_line() is based on finding the middle difference of each line
47812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    on the screen; vis:
47912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
48012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			     /old first difference
48112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/beginning of line   |              /old last same       /old EOL
48212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	v		     v              v                    v
48312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaold:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
48412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialanew:	eddie> Oh, my little buggy says to me, as lurgid as
48512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	^		     ^        ^			   ^
48612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	\beginning of line   |        \new last same	   \new end of line
48712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			     \new first difference
48812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
48912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    all are character pointers for the sake of speed.  Special cases for
49012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    no differences, as well as for end of line additions must be handled.
49112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala**************************************************************** */
49212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
49312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* Minimum at which doing an insert it "worth it".  This should be about
49412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * half the "cost" of going into insert mode, inserting a character, and
49512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * going back out.  This should really be calculated from the termcap
49612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * data...  For the moment, a good number for ANSI terminals.
49712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
49812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	MIN_END_KEEP	4
49912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
50012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
50112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_update_line(EditLine *el, Char *old, Char *new, int i)
50212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
50312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *o, *n, *p, c;
50412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *ofd, *ols, *oe, *nfd, *nls, *ne;
50512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *osb, *ose, *nsb, *nse;
50612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int fx, sx;
50712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t len;
50812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
50912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
51012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * find first diff
51112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
51212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (o = old, n = new; *o && (*o == *n); o++, n++)
51312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		continue;
51412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ofd = o;
51512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nfd = n;
51612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
51712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
51812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Find the end of both old and new
51912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
52012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (*o)
52112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		o++;
52212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
52312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Remove any trailing blanks off of the end, being careful not to
52412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * back up past the beginning.
52512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
52612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (ofd < o) {
52712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (o[-1] != ' ')
52812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
52912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		o--;
53012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
53112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	oe = o;
53212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*oe = '\0';
53312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
53412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (*n)
53512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		n++;
53612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
53712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* remove blanks from end of new */
53812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (nfd < n) {
53912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (n[-1] != ' ')
54012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
54112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		n--;
54212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
54312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ne = n;
54412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*ne = '\0';
54512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
54612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
54712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * if no diff, continue to next line of redraw
54812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
54912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (*ofd == '\0' && *nfd == '\0') {
55012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1, (__F, "no difference.\r\n"));
55112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
55212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
55312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
55412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * find last same pointer
55512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
55612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while ((o > ofd) && (n > nfd) && (*--o == *--n))
55712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		continue;
55812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ols = ++o;
55912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nls = ++n;
56012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
56112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
56212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * find same begining and same end
56312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
56412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	osb = ols;
56512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nsb = nls;
56612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ose = ols;
56712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nse = nls;
56812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
56912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
57012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * case 1: insert: scan from nfd to nls looking for *ofd
57112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
57212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (*ofd) {
57312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (c = *ofd, n = nfd; n < nls; n++) {
57412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (c == *n) {
57512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				for (o = ofd, p = n;
57612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    p < nls && o < ols && *o == *p;
57712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    o++, p++)
57812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					continue;
57912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
58012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * if the new match is longer and it's worth
58112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * keeping, then we take it
58212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
58312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (((nse - nsb) < (p - n)) &&
58412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (2 * (p - n) > n - nfd)) {
58512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					nsb = n;
58612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					nse = p;
58712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					osb = ofd;
58812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					ose = o;
58912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
59012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
59112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
59212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
59312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
59412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * case 2: delete: scan from ofd to ols looking for *nfd
59512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
59612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (*nfd) {
59712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (c = *nfd, o = ofd; o < ols; o++) {
59812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (c == *o) {
59912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				for (n = nfd, p = o;
60012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    p < ols && n < nls && *p == *n;
60112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    p++, n++)
60212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					continue;
60312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
60412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * if the new match is longer and it's worth
60512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * keeping, then we take it
60612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
60712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (((ose - osb) < (p - o)) &&
60812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (2 * (p - o) > o - ofd)) {
60912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					nsb = nfd;
61012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					nse = n;
61112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					osb = o;
61212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					ose = p;
61312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
61412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
61512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
61612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
61712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
61812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Pragmatics I: If old trailing whitespace or not enough characters to
61912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * save to be worth it, then don't save the last same info.
62012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
62112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((oe - ols) < MIN_END_KEEP) {
62212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ols = oe;
62312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		nls = ne;
62412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
62512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
62612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Pragmatics II: if the terminal isn't smart enough, make the data
62712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * dumber so the smart update doesn't try anything fancy
62812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
62912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
63012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
63112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * fx is the number of characters we need to insert/delete: in the
63212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * beginning to bring the two same begins together
63312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
63412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	fx = (int)((nsb - nfd) - (osb - ofd));
63512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
63612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * sx is the number of characters we need to insert/delete: in the
63712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * end to bring the two same last parts together
63812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
63912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sx = (int)((nls - nse) - (ols - ose));
64012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
64112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_INSERT) {
64212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (fx > 0) {
64312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			osb = ols;
64412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ose = ols;
64512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nsb = nls;
64612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nse = nls;
64712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
64812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (sx > 0) {
64912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ols = oe;
65012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nls = ne;
65112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
65212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if ((ols - ofd) < (nls - nfd)) {
65312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ols = oe;
65412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nls = ne;
65512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
65612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
65712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_DELETE) {
65812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (fx < 0) {
65912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			osb = ols;
66012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ose = ols;
66112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nsb = nls;
66212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nse = nls;
66312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
66412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (sx < 0) {
66512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ols = oe;
66612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nls = ne;
66712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
66812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if ((ols - ofd) > (nls - nfd)) {
66912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ols = oe;
67012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			nls = ne;
67112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
67212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
67312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
67412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Pragmatics III: make sure the middle shifted pointers are correct if
67512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * they don't point to anything (we may have moved ols or nls).
67612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
67712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* if the change isn't worth it, don't bother */
67812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* was: if (osb == ose) */
67912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((ose - osb) < MIN_END_KEEP) {
68012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		osb = ols;
68112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ose = ols;
68212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		nsb = nls;
68312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		nse = nls;
68412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
68512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
68612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Now that we are done with pragmatics we recompute fx, sx
68712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
68812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	fx = (int)((nsb - nfd) - (osb - ofd));
68912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sx = (int)((nls - nse) - (ols - ose));
69012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
69112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
69212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
69312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ofd - old, osb - old, ose - old, ols - old, oe - old));
69412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
69512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		nfd - new, nsb - new, nse - new, nls - new, ne - new));
69612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
69712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		"xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
69812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F,
69912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		"xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"));
70012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_REFRESH
70112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "old- oe", old, oe);
70212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "new- ne", new, ne);
70312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "old-ofd", old, ofd);
70412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "new-nfd", new, nfd);
70512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "ofd-osb", ofd, osb);
70612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "nfd-nsb", nfd, nsb);
70712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "osb-ose", osb, ose);
70812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "nsb-nse", nsb, nse);
70912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "ose-ols", ose, ols);
71012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "nse-nls", nse, nls);
71112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "ols- oe", ols, oe);
71212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_printstr(el, "nls- ne", nls, ne);
71312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_REFRESH */
71412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
71512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
71612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * el_cursor.v to this line i MUST be in this routine so that if we
71712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * don't have to change the line, we don't move to it. el_cursor.h to
71812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * first diff char
71912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
72012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_line(el, i);
72112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
72212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
72312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * at this point we have something like this:
72412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         *
72512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * /old                  /ofd    /osb               /ose    /ols     /oe
72612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * v.....................v       v..................v       v........v
72712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
72812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
72912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * ^.....................^     ^..................^       ^........^
73012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * \new                  \nfd  \nsb               \nse     \nls    \ne
73112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         *
73212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * fx is the difference in length between the chars between nfd and
73312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * nsb, and the chars between ofd and osb, and is thus the number of
73412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * characters to delete if < 0 (new is shorter than old, as above),
73512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * or insert (new is longer than short).
73612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         *
73712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * sx is the same for the second differences.
73812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
73912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
74012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
74112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * if we have a net insert on the first difference, AND inserting the
74212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
74312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * character (which is ne if nls != ne, otherwise is nse) off the edge
74412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * of the screen (el->el_terminal.t_size.h) else we do the deletes first
74512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * so that we keep everything we need to.
74612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
74712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
74812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
74912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * if the last same is the same like the end, there is no last same
75012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * part, otherwise we want to keep the last same part set p to the
75112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * last useful old character
75212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
75312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	p = (ols != oe) ? oe : ose;
75412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
75512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
75612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * if (There is a diffence in the beginning) && (we need to insert
75712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         *   characters) && (the number of characters to insert is less than
75812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         *   the term width)
75912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 *	We need to do an insert!
76012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * else if (we need to delete characters)
76112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 *	We need to delete characters!
76212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * else
76312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 *	No insert or delete
76412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
76512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((nsb != nfd) && fx > 0 &&
76612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    ((p - old) + fx <= el->el_terminal.t_size.h)) {
76712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1,
76812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    (__F, "first diff insert at %d...\r\n", nfd - new));
76912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
77012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Move to the first char to insert, where the first diff is.
77112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
77212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_char(el, (int)(nfd - new));
77312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
77412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Check if we have stuff to keep at end
77512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
77612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (nsb != ne) {
77712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
77812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
77912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * insert fx chars of new starting at nfd
78012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
78112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (fx > 0) {
78212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
78312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				"ERROR: cannot insert in early first diff\n"));
78412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_insertwrite(el, nfd, fx);
78512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				re_insert(el, old, (int)(ofd - old),
78612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    el->el_terminal.t_size.h, nfd, fx);
78712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
78812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
78912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nsb-nfd) - fx chars of new starting at
79012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * (nfd + fx)
79112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			 */
79212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			len = (size_t) ((nsb - nfd) - fx);
79312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, (nfd + fx), len);
79412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__strncopy(ofd + fx, nfd + fx, len);
79512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
79612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
79712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			len = (size_t)(nsb - nfd);
79812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nfd, len);
79912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__strncopy(ofd, nfd, len);
80012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
80112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * Done
80212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
80312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return;
80412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
80512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (fx < 0) {
80612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1,
80712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    (__F, "first diff delete at %d...\r\n", ofd - old));
80812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
80912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * move to the first char to delete where the first diff is
81012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
81112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_char(el, (int)(ofd - old));
81212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
81312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Check if we have stuff to save
81412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
81512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (osb != oe) {
81612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
81712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
81812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * fx is less than zero *always* here but we check
81912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * for code symmetry
82012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
82112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (fx < 0) {
82212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
82312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "ERROR: cannot delete in first diff\n"));
82412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_deletechars(el, -fx);
82512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				re_delete(el, old, (int)(ofd - old),
82612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    el->el_terminal.t_size.h, -fx);
82712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
82812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
82912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nsb-nfd) chars of new starting at nfd
83012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
83112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			len = (size_t) (nsb - nfd);
83212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nfd, len);
83312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__strncopy(ofd, nfd, len);
83412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
83512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
83612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F,
83712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "but with nothing left to save\r\n"));
83812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
83912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nsb-nfd) chars of new starting at nfd
84012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
84112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
84212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_clear_eol(el, fx, sx,
84312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    (int)((oe - old) - (ne - new)));
84412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
84512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * Done
84612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
84712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return;
84812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
84912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
85012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		fx = 0;
85112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
85212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
85312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1, (__F,
85412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "second diff delete at %d...\r\n", (ose - old) + fx));
85512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
85612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Check if we have stuff to delete
85712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
85812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
85912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * fx is the number of characters inserted (+) or deleted (-)
86012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
86112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
86212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_char(el, (int)((ose - old) + fx));
86312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
86412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Check if we have stuff to save
86512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
86612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ols != oe) {
86712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
86812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
86912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * Again a duplicate test.
87012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
87112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (sx < 0) {
87212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
87312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "ERROR: cannot delete in second diff\n"));
87412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_deletechars(el, -sx);
87512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
87612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
87712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nls-nse) chars of new starting at nse
87812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
87912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nse, (size_t)(nls - nse));
88012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
88112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F,
88212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "but with nothing left to save\r\n"));
88312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nse, (size_t)(nls - nse));
88412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_clear_eol(el, fx, sx,
88512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    (int)((oe - old) - (ne - new)));
88612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
88712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
88812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
88912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
89012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
89112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
89212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
89312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    nfd - new));
89412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
89512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_char(el, (int)(nfd - new));
89612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
89712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Check if we have stuff to keep at the end
89812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
89912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (nsb != ne) {
90012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
90112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
90212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * We have to recalculate fx here because we set it
90312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * to zero above as a flag saying that we hadn't done
90412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * an early first insert.
90512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
90612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			fx = (int)((nsb - nfd) - (osb - ofd));
90712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (fx > 0) {
90812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
90912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * insert fx chars of new starting at nfd
91012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
91112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
91212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 "ERROR: cannot insert in late first diff\n"));
91312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_insertwrite(el, nfd, fx);
91412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				re_insert(el, old, (int)(ofd - old),
91512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    el->el_terminal.t_size.h, nfd, fx);
91612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
91712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
91812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nsb-nfd) - fx chars of new starting at
91912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * (nfd + fx)
92012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			 */
92112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			len = (size_t) ((nsb - nfd) - fx);
92212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, (nfd + fx), len);
92312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__strncopy(ofd + fx, nfd + fx, len);
92412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
92512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
92612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			len = (size_t) (nsb - nfd);
92712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nfd, len);
92812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__strncopy(ofd, nfd, len);
92912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
93012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
93112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
93212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * line is now NEW up to nse
93312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
93412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (sx >= 0) {
93512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ELRE_DEBUG(1, (__F,
93612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "second diff insert at %d...\r\n", (int)(nse - new)));
93712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_char(el, (int)(nse - new));
93812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ols != oe) {
93912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
94012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (sx > 0) {
94112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* insert sx chars of new starting at nse */
94212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
94312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "ERROR: cannot insert in second diff\n"));
94412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_insertwrite(el, nse, sx);
94512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
94612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
94712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         * write (nls-nse) - sx chars of new starting at
94812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			 * (nse + sx)
94912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
95012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, (nse + sx),
95112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    (size_t)((nls - nse) - sx));
95212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
95312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
95412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, nse, (size_t)(nls - nse));
95512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
95612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*
95712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	                 * No need to do a clear-to-end here because we were
95812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	                 * doing a second insert, so we will have over
95912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	                 * written all of the old string.
96012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		         */
96112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
96212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
96312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ELRE_DEBUG(1, (__F, "done.\r\n"));
96412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
96512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
96612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
96712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re__copy_and_pad():
96812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Copy string and pad with spaces
96912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
97012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
97112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare__copy_and_pad(Char *dst, const Char *src, size_t width)
97212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
97312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t i;
97412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
97512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < width; i++) {
97612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*src == '\0')
97712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
97812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*dst++ = *src++;
97912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
98012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
98112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (; i < width; i++)
98212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*dst++ = ' ';
98312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
98412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*dst = '\0';
98512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
98612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
98712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
98812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_refresh_cursor():
98912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Move to the new cursor position
99012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
99112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
99212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_refresh_cursor(EditLine *el)
99312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
99412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *cp;
99512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int h, v, th, w;
99612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
99712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_line.cursor >= el->el_line.lastchar) {
99812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (el->el_map.current == el->el_map.alt
99912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    && el->el_line.lastchar != el->el_line.buffer)
100012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_line.cursor = el->el_line.lastchar - 1;
100112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else
100212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_line.cursor = el->el_line.lastchar;
100312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
100412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
100512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* first we must find where the cursor is... */
100612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	h = el->el_prompt.p_pos.h;
100712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	v = el->el_prompt.p_pos.v;
100812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	th = el->el_terminal.t_size.h;	/* optimize for speed */
100912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
101012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* do input buffer to el->el_line.cursor */
101112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
101212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                switch (ct_chr_class(*cp)) {
101312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case CHTYPE_NL:  /* handle newline in data part too */
101412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			h = 0;
101512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			v++;
101612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
101712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case CHTYPE_TAB: /* if a tab, to next tab stop */
101812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			while (++h & 07)
101912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				continue;
102012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
102112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		default:
102212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			w = Width(*cp);
102312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (w > 1 && h + w > th) { /* won't fit on line */
102412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				h = 0;
102512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				v++;
102612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
102712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			h += ct_visual_width(*cp);
102812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
102912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                }
103012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
103112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (h >= th) {	/* check, extra long tabs picked up here also */
103212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			h -= th;
103312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			v++;
103412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
103512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
103612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala        /* if we have a next character, and it's a doublewidth one, we need to
103712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * check whether we need to linebreak for it to fit */
103812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala        if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
103912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                if (h + w > th) {
104012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                    h = 0;
104112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                    v++;
104212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                }
104312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
104412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* now go there */
104512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_line(el, v);
104612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_move_to_char(el, h);
104712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__flush(el);
104812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
104912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
105012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
105112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_fastputc():
105212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Add a character fast.
105312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
105412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
105512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_fastputc(EditLine *el, Int c)
105612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
105712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int w = Width((Char)c);
105812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
105912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    re_fastputc(el, ' ');
106012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
106112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__putc(el, c);
106212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
106312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	while (--w > 0)
106412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_display[el->el_cursor.v][el->el_cursor.h++]
106512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			= MB_FILL_CHAR;
106612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
106712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_cursor.h >= el->el_terminal.t_size.h) {
106812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* if we must overflow */
106912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_cursor.h = 0;
107012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
107112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
107212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * If we would overflow (input is longer than terminal size),
107312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * emulate scroll by dropping first line and shuffling the rest.
107412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * We do this via pointer shuffling - it's safe in this case
107512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * and we avoid memcpy().
107612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
107712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
107812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			int i, lins = el->el_terminal.t_size.v;
107912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			Char *firstline = el->el_display[0];
108012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
108112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			for(i = 1; i < lins; i++)
108212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				el->el_display[i - 1] = el->el_display[i];
108312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
108412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re__copy_and_pad(firstline, STR(""), (size_t)0);
108512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_display[i - 1] = firstline;
108612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
108712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_cursor.v++;
108812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_refresh.r_oldcv++;
108912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
109012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (EL_HAS_AUTO_MARGINS) {
109112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (EL_HAS_MAGIC_MARGINS) {
109212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal__putc(el, ' ');
109312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal__putc(el, '\b');
109412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
109512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
109612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal__putc(el, '\r');
109712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal__putc(el, '\n');
109812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
109912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
110012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
110112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
110212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
110312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_fastaddc():
110412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	we added just one char, handle it fast.
110512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Assumes that screen cursor == real cursor
110612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
110712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
110812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_fastaddc(EditLine *el)
110912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
111012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char c;
111112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int rhdiff;
111212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
111312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	c = el->el_line.cursor[-1];
111412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
111512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
111612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_refresh(el);	/* too hard to handle */
111712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
111812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
111912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
112012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    el->el_rprompt.p_pos.h;
112112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_rprompt.p_pos.h && rhdiff < 3) {
112212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_refresh(el);	/* clear out rprompt if less than 1 char gap */
112312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
112412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}			/* else (only do at end of line, no TAB) */
112512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (ct_chr_class(c)) {
112612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_TAB: /* already handled, should never happen here */
112712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
112812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_NL:
112912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_PRINT:
113012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		re_fastputc(el, c);
113112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
113212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_ASCIICTL:
113312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case CHTYPE_NONPRINT: {
113412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char visbuf[VISUAL_WIDTH_MAX];
113512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ssize_t i, n =
113612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
113712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = 0; n-- > 0; ++i)
113812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_fastputc(el, visbuf[i]);
113912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
114012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
114112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
114212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__flush(el);
114312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
114412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
114512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
114612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_clear_display():
114712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	clear the screen buffers so that new new prompt starts fresh.
114812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
114912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
115012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_clear_display(EditLine *el)
115112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
115212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
115312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
115412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_cursor.v = 0;
115512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_cursor.h = 0;
115612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < el->el_terminal.t_size.v; i++)
115712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_display[i][0] = '\0';
115812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_refresh.r_oldcv = 0;
115912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
116012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* re_clear_lines():
116312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Make sure all lines are *really* blank
116412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
116512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
116612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialare_clear_lines(EditLine *el)
116712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
116812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (EL_CAN_CEOL) {
117012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int i;
117112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
117212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/* for each line on the screen */
117312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_move_to_line(el, i);
117412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_move_to_char(el, 0);
117512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_clear_EOL(el, el->el_terminal.t_size.h);
117612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
117712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
117812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_move_to_line(el, el->el_refresh.r_oldcv);
117912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					/* go to last line */
118012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\r');	/* go to BOL */
118112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\n');	/* go to new line */
118212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
118312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
1184