Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Mar 2005 19:33:05 -0700 (MST)
From:      Phil Oleson <oz@nixil.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/79418: [patch] libedit sync from netbsd cvs
Message-ID:  <200504010233.j312X5hL083878@nixil.net>
Resent-Message-ID: <200504010240.j312eBbf000452@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         79418
>Category:       bin
>Synopsis:       [patch] libedit sync from netbsd cvs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 01 02:40:10 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Phil Oleson
>Release:        FreeBSD 5.4-PRERELEASE
>Organization:
N/A
>Environment:
System: FreeBSD box2.nixil.net 5.4-PRERELEASE FreeBSD 5.4-PRERELEASE #3: Thu Mar 10 09:10:24 MST 2005     root@box2.nixil.net:/usr/obj/usr/src/sys/box2  i386


>Description:
	libedit in /usr/lib is old.. 
>How-To-Repeat:
	N/A
>Fix:

	Apply patch.. 

        I was a bit unsure if I should increment 'SHLIB_MAJOR' to 5. There were some
        small changes to the API, exposed some tok_xx functions but it also removed 
        el_data_get() & el_data_set().

--- libedit-sync-patch begins here ---
diff --exclude=CVS -ruN src.orig/include/histedit.h src/include/histedit.h
--- src.orig/include/histedit.h	Mon Jul 14 10:31:20 2003
+++ src/include/histedit.h	Thu Mar 31 18:06:46 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)histedit.h	8.2 (Berkeley) 1/3/94
- *	$NetBSD: histedit.h,v 1.15 2000/02/28 17:41:05 chopps Exp $
- * $FreeBSD: src/include/histedit.h,v 1.9 2003/07/14 16:31:20 imp Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -52,6 +49,7 @@
 /*
  * ==== Editing ====
  */
+
 typedef struct editline EditLine;
 
 /*
@@ -63,7 +61,6 @@
 	const char	*lastchar;
 } LineInfo;
 
-
 /*
  * EditLine editor function return codes.
  * For user-defined function interface
@@ -83,16 +80,15 @@
  * Initialization, cleanup, and resetting
  */
 EditLine	*el_init(const char *, FILE *, FILE *, FILE *);
-void		 el_reset(EditLine *);
 void		 el_end(EditLine *);
-
+void		 el_reset(EditLine *);
 
 /*
  * Get a line, a character or push a string back in the input queue
  */
 const char	*el_gets(EditLine *, int *);
 int		 el_getc(EditLine *, char *);
-void		 el_push(EditLine *, const char *);
+void		 el_push(EditLine *, char *);
 
 /*
  * Beep!
@@ -103,7 +99,7 @@
  * High level function internals control
  * Parses argc, argv array and executes builtin editline commands
  */
-int		 el_parse(EditLine *, int, char **);
+int		 el_parse(EditLine *, int, const char **);
 
 /*
  * Low level editline access functions
@@ -128,6 +124,12 @@
 #define	EL_HIST		10	/* , hist_fun_t, const char *);	*/
 #define	EL_EDITMODE	11	/* , int);			*/
 #define	EL_RPROMPT	12	/* , el_pfunc_t);		*/
+#define	EL_GETCFN	13	/* , el_rfunc_t);		*/
+#define	EL_CLIENTDATA	14	/* , void *);			*/
+#define	EL_UNBUFFERED	15	/* , int);			*/
+#define	EL_PREP_TERM    16      /* , int);                      */
+
+#define EL_BUILTIN_GETCFN	(NULL)
 
 /*
  * Source named file or $PWD/.editrc or $HOME/.editrc
@@ -141,13 +143,6 @@
  */
 void		 el_resize(EditLine *);
 
-
-/*
- * Set user private data.
- */
-void            el_data_set    __P((EditLine *, void *));
-void *          el_data_get    __P((EditLine *));
-
 /*
  * User-defined function interface.
  */
@@ -155,6 +150,7 @@
 int		 el_insertstr(EditLine *, const char *);
 void		 el_deletestr(EditLine *, int);
 
+
 /*
  * ==== History ====
  */
@@ -176,14 +172,13 @@
 
 #define	H_FUNC		 0	/* , UTSL		*/
 #define	H_SETSIZE	 1	/* , const int);	*/
-#define H_EVENT		 1	/* , const int);	*/
 #define	H_GETSIZE	 2	/* , void);		*/
 #define	H_FIRST		 3	/* , void);		*/
 #define	H_LAST		 4	/* , void);		*/
 #define	H_PREV		 5	/* , void);		*/
 #define	H_NEXT		 6	/* , void);		*/
 #define	H_CURR		 8	/* , const int);	*/
-#define	H_SET		 7	/* , void);		*/
+#define	H_SET		 7	/* , int);		*/
 #define	H_ADD		 9	/* , const char *);	*/
 #define	H_ENTER		10	/* , const char *);	*/
 #define	H_APPEND	11	/* , const char *);	*/
@@ -195,6 +190,26 @@
 #define	H_LOAD		17	/* , const char *);	*/
 #define	H_SAVE		18	/* , const char *);	*/
 #define	H_CLEAR		19	/* , void);		*/
+#define	H_SETUNIQUE	20	/* , int);		*/
+#define	H_GETUNIQUE	21	/* , void);		*/
+
+
+/*
+ * ==== Tokenization ====
+ */
+
+typedef struct tokenizer Tokenizer;
+
+/*
+ * String tokenization functions, using simplified sh(1) quoting rules
+ */
+Tokenizer	*tok_init(const char *);
+void		 tok_end(Tokenizer *);
+void		 tok_reset(Tokenizer *);
+int		 tok_line(Tokenizer *, const LineInfo *,
+		    int *, const char ***, int *, int *);
+int		 tok_str(Tokenizer *, const char *,
+		    int *, const char ***);
 
 __END_DECLS
 
diff --exclude=CVS -ruN src.orig/lib/libedit/Makefile src/lib/libedit/Makefile
--- src.orig/lib/libedit/Makefile	Mon Aug 18 09:25:38 2003
+++ src/lib/libedit/Makefile	Thu Mar 31 18:08:59 2005
@@ -1,68 +1,95 @@
-#	$NetBSD: Makefile,v 1.19 2000/08/15 12:01:40 mrg Exp $
+#	$NetBSD: Makefile,v 1.29 2003/12/05 13:37:48 lukem Exp $
 #	@(#)Makefile	8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libedit/Makefile,v 1.28 2003/08/18 15:25:38 obrien Exp $
+# $FreeBSD$
 
+USE_SHLIBDIR=	yes
+
+WARNS=	3
 LIB=	edit
 SHLIB_MAJOR=	4
-SHLIBDIR?= /lib
+SHLIBDIR?=	/lib
 
 OSRCS=	chared.c common.c el.c emacs.c fcns.c help.c hist.c key.c map.c \
 	parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c
 
-DPADD=	${LIBNCURSES}
-LDADD=	-lncurses
+DPADD=  ${LIBNCURSES}
+LDADD=  -lncurses
 
 MAN=	editline.3 editrc.5
 
-MLINKS=	editline.3 el_deletestr.3 editline.3 el_end.3 editline.3 el_init.3 \
-	editline.3 el_get.3 editline.3 el_getc.3 editline.3 el_gets.3 \
-	editline.3 history.3 editline.3 history_end.3 \
-	editline.3 history_init.3 editline.3 el_insertstr.3 \
-	editline.3 el_line.3 editline.3 el_parse.3 editline.3 el_push.3 \
-	editline.3 el_reset.3 editline.3 el_resize.3 editline.3 el_set.3 \
-	editline.3 el_source.3
+MLINKS=	editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \
+	editline.3 el_gets.3 editline.3 el_getc.3 editline.3 el_push.3 \
+	editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_get.3 \
+	editline.3 el_source.3 editline.3 el_resize.3 editline.3 el_line.3 \
+	editline.3 el_insertstr.3 editline.3 el_deletestr.3 \
+	editline.3 history_init.3 editline.3 history_end.3 \
+	editline.3 history.3 \
+	editline.3 tok_init.3 editline.3 tok_end.3 editline.3 tok_reset.3 \
+	editline.3 tok_line.3 editline.3 tok_str.3
 
 # For speed and debugging
-#SRCS=   ${OSRCS} tokenizer.c history.c
+#SRCS=   ${OSRCS} tokenizer.c history.c readline.c
 # For protection
 SRCS=	editline.c tokenizer.c history.c
-SRCS+=	common.h emacs.h fcns.h help.h vi.h
-CLEANFILES+= common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h
 
-CFLAGS+= -I. -I${.CURDIR}
-CFLAGS+= #-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
-CFLAGS+= #-DDEBUG_PASTE
-
-AHDR=	vi.h emacs.h common.h
-ASRC=	${.CURDIR}/vi.c ${.CURDIR}/emacs.c ${.CURDIR}/common.c
-
-.for hdr in vi emacs common
-${hdr}.h: ${hdr}.c makelist
-	sh ${.CURDIR}/makelist -h ${.CURDIR}/${hdr}.c > ${.TARGET}
-.endfor
+LIBEDITDIR?=${.CURDIR}
 
-fcns.h: ${AHDR} makelist
-	sh ${.CURDIR}/makelist -fh ${AHDR} > ${.TARGET}
+#INCS= histedit.h
+INCSDIR=/usr/include
+HOST_SH=sh
+
+CLEANFILES+=editline.c
+CLEANFILES+=common.h.tmp editline.c.tmp emacs.h.tmp fcns.c.tmp fcns.h.tmp
+CLEANFILES+=help.c.tmp help.h.tmp vi.h.tmp
+CFLAGS+=-I. -I${LIBEDITDIR} 
+CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../../include
+CFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
+CFLAGS+=#-DDEBUG_PASTE -DDEBUG_EDIT
+
+AHDR=vi.h emacs.h common.h 
+ASRC=${LIBEDITDIR}/vi.c ${LIBEDITDIR}/emacs.c ${LIBEDITDIR}/common.c
+
+DPSRCS+=	${AHDR} fcns.h help.h fcns.c help.c
+CLEANFILES+=	${AHDR} fcns.h help.h fcns.c help.c
+
+vi.h: vi.c makelist
+	${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c \
+	    > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
+
+emacs.h: emacs.c makelist
+	${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/emacs.c \
+	    > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
+
+common.h: common.c makelist
+	${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/common.c \
+	    > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
 
-fcns.c: ${AHDR} fcns.h makelist
-	sh ${.CURDIR}/makelist -fc ${AHDR} > ${.TARGET}
+fcns.h: ${AHDR} makelist
+	${HOST_SH} ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
 
-help.c: ${ASRC} makelist
-	sh ${.CURDIR}/makelist -bc ${ASRC} > ${.TARGET}
+fcns.c: ${AHDR} fcns.h help.h makelist
+	${HOST_SH} ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
+
+help.c: ${ASRC} makelist 
+	${HOST_SH} ${LIBEDITDIR}/makelist -bc ${ASRC} > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
 
 help.h: ${ASRC} makelist
-	sh ${.CURDIR}/makelist -bh ${ASRC} > ${.TARGET}
+	${HOST_SH} ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
 
 editline.c: ${OSRCS}
-	sh ${.CURDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET}
-
-# minimal dependency to make "make depend" optional
-editline.o editline.po editline.So editline.ln:	\
-	common.h emacs.h fcns.c fcns.h help.c help.h vi.h
-
-test.o: ${.CURDIR}/TEST/test.c
+	${HOST_SH} ${LIBEDITDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET}.tmp && \
+	    mv ${.TARGET}.tmp ${.TARGET}
 
-test: test.o libedit.a ${DPADD} ${LIBTERMCAP}
-	${CC} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD}
+test.o:	${LIBEDITDIR}/TEST/test.c
+	
+test:	libedit.a test.o 
+	${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermcap
 
 .include <bsd.lib.mk>
diff --exclude=CVS -ruN src.orig/lib/libedit/TEST/test.c src/lib/libedit/TEST/test.c
--- src.orig/lib/libedit/TEST/test.c	Mon Oct  1 02:41:27 2001
+++ src/lib/libedit/TEST/test.c	Wed Mar 30 21:31:02 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: test.c,v 1.15 2003/12/08 12:03:01 lukem Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,22 +32,24 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
+#include "config.h"
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n");
 #endif /* not lint */
 
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)test.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: test.c,v 1.15 2003/12/08 12:03:01 lukem Exp $");
+__FBSDID("$FreeBSD$");
+#endif
 #endif /* not lint && not SCCSID */
-__RCSID("$NetBSD: test.c,v 1.8 1999/09/21 00:07:03 lukem Exp $");
-__FBSDID("$FreeBSD: src/lib/libedit/TEST/test.c,v 1.4 2001/10/01 08:41:27 obrien Exp $");
 
 /*
  * test.c: A little test program
  */
-#include "sys.h"
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
@@ -60,7 +60,6 @@
 #include <dirent.h>
 
 #include "histedit.h"
-#include "tokenizer.h"
 
 static int continuation = 0;
 static EditLine *el = NULL;
@@ -73,8 +72,8 @@
 static char *
 prompt(EditLine *el)
 {
-	static char a[] = "Edit$";
-	static char b[] = "Edit>";
+	static char a[] = "Edit$ ";
+	static char b[] = "Edit> ";
 
 	return (continuation ? b : a);
 }
@@ -125,7 +124,10 @@
 	int num;
 	const char *buf;
 	Tokenizer *tok;
-	int lastevent = 0, ncontinuation;
+#if 0
+	int lastevent = 0;
+#endif
+	int ncontinuation;
 	History *hist;
 	HistEvent ev;
 
@@ -169,17 +171,35 @@
 	el_source(el, NULL);
 
 	while ((buf = el_gets(el, &num)) != NULL && num != 0)  {
-		int ac;
-		char **av;
+		int ac, cc, co;
 #ifdef DEBUG
-		(void) fprintf(stderr, "got %d %s", num, buf);
+		int i;
+#endif
+		const char **av;
+		const LineInfo *li;
+		li = el_line(el);
+#ifdef DEBUG
+		(void) fprintf(stderr, "==> got %d %s", num, buf);
+		(void) fprintf(stderr, "  > li `%.*s_%.*s'\n",
+		    (li->cursor - li->buffer), li->buffer,
+		    (li->lastchar - 1 - li->cursor),
+		    (li->cursor >= li->lastchar) ? "" : li->cursor);
+
 #endif
 		if (!continuation && num == 1)
 			continue;
 
-		if (tok_line(tok, buf, &ac, &av) > 0)
-			ncontinuation = 1;
-
+		ac = cc = co = 0;
+		ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
+		if (ncontinuation < 0) {
+			(void) fprintf(stderr, "Internal error\n");
+			continuation = 0;
+			continue;
+		}
+#ifdef DEBUG
+		(void) fprintf(stderr, "  > nc %d ac %d cc %d co %d\n",
+		    ncontinuation, ac, cc, co);
+#endif
 #if 0
 		if (continuation) {
 			/*
@@ -187,7 +207,7 @@
 			 * moved around in history.
 			 */
 			if (history(hist, &ev, H_SET, lastevent) == -1)
-				err(1, "%d: %s\n", lastevent, ev.str);
+				err(1, "%d: %s", lastevent, ev.str);
 			history(hist, &ev, H_ADD , buf);
 		} else {
 			history(hist, &ev, H_ENTER, buf);
@@ -200,6 +220,18 @@
 
 		continuation = ncontinuation;
 		ncontinuation = 0;
+		if (continuation)
+			continue;
+#ifdef DEBUG
+		for (i = 0; i < ac; i++) {
+			(void) fprintf(stderr, "  > arg# %2d ", i);
+			if (i != cc)
+				(void) fprintf(stderr, "`%s'\n", av[i]);
+			else
+				(void) fprintf(stderr, "`%.*s_%s'\n",
+				    co, av[i], av[i] + co);
+		}
+#endif
 
 		if (strcmp(av[0], "history") == 0) {
 			int rv;
@@ -235,7 +267,7 @@
 		} else if (el_parse(el, ac, av) == -1) {
 			switch (fork()) {
 			case 0:
-				execvp(av[0], av);
+				execvp(av[0], (char *const *)av);
 				perror(av[0]);
 				_exit(1);
 				/*NOTREACHED*/
diff --exclude=CVS -ruN src.orig/lib/libedit/chared.c src/lib/libedit/chared.c
--- src.orig/lib/libedit/chared.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/chared.c	Thu Mar 31 17:54:05 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,21 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: chared.c,v 1.13 2001/04/13 01:04:19 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)chared.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/chared.c,v 1.8 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/chared.c,v 1.7 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * chared.c: Character editor utilities
  */
-#include "sys.h"
-
 #include <stdlib.h>
 #include "el.h"
 
@@ -57,17 +55,36 @@
  *	Handle state for the vi undo command
  */
 protected void
-cv_undo(EditLine *el,int action, size_t size, char *ptr)
+cv_undo(EditLine *el)
 {
 	c_undo_t *vu = &el->el_chared.c_undo;
-	vu->action = action;
-	vu->ptr    = ptr;
-	vu->isize  = size;
-	(void) memcpy(vu->buf, vu->ptr, size);
-#ifdef DEBUG_UNDO
-	(void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
-	       vu->ptr, vu->isize, vu->dsize);
-#endif
+	c_redo_t *r = &el->el_chared.c_redo;
+	uint size;
+
+	/* Save entire line for undo */
+	size = el->el_line.lastchar - el->el_line.buffer;
+	vu->len = size;
+	vu->cursor = el->el_line.cursor - el->el_line.buffer;
+	memcpy(vu->buf, el->el_line.buffer, size);
+
+	/* save command info for redo */
+	r->count = el->el_state.doingarg ? el->el_state.argument : 0;
+	r->action = el->el_chared.c_vcmd.action;
+	r->pos = r->buf;
+	r->cmd = el->el_state.thiscmd;
+	r->ch = el->el_state.thisch;
+}
+
+/* cv_yank():
+ *	Save yank/delete data for paste
+ */
+protected void
+cv_yank(EditLine *el, const char *ptr, int size)
+{
+	c_kill_t *k = &el->el_chared.c_kill;
+
+	memcpy(k->buf, ptr, size +0u);
+	k->last = k->buf + size;
 }
 
 
@@ -79,8 +96,10 @@
 {
 	char *cp;
 
-	if (el->el_line.lastchar + num >= el->el_line.limit)
-		return;			/* can't go past end of buffer */
+	if (el->el_line.lastchar + num >= el->el_line.limit) {
+		if (!ch_enlargebufs(el, num +0u))
+			return;		/* can't go past end of buffer */
+	}
 
 	if (el->el_line.cursor < el->el_line.lastchar) {
 		/* if I must move chars */
@@ -101,12 +120,14 @@
 	if (el->el_line.cursor + num > el->el_line.lastchar)
 		num = el->el_line.lastchar - el->el_line.cursor;
 
+	if (el->el_map.current != el->el_map.emacs) {
+		cv_undo(el);
+		cv_yank(el, el->el_line.cursor, num);
+	}
+
 	if (num > 0) {
 		char *cp;
 
-		if (el->el_map.current != el->el_map.emacs)
-			cv_undo(el, INSERT, (size_t)num, el->el_line.cursor);
-
 		for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
 			*cp = cp[num];
 
@@ -115,6 +136,21 @@
 }
 
 
+/* c_delafter1():
+ *	Delete the character after the cursor, do not yank
+ */
+protected void
+c_delafter1(EditLine *el)
+{
+	char *cp;
+
+	for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+		*cp = cp[1];
+
+	el->el_line.lastchar--;
+}
+
+
 /* c_delbefore():
  *	Delete num characters before the cursor
  */
@@ -125,13 +161,14 @@
 	if (el->el_line.cursor - num < el->el_line.buffer)
 		num = el->el_line.cursor - el->el_line.buffer;
 
+	if (el->el_map.current != el->el_map.emacs) {
+		cv_undo(el);
+		cv_yank(el, el->el_line.cursor - num, num);
+	}
+
 	if (num > 0) {
 		char *cp;
 
-		if (el->el_map.current != el->el_map.emacs)
-			cv_undo(el, INSERT, (size_t)num,
-			    el->el_line.cursor - num);
-
 		for (cp = el->el_line.cursor - num;
 		    cp <= el->el_line.lastchar;
 		    cp++)
@@ -142,38 +179,52 @@
 }
 
 
+/* c_delbefore1():
+ *	Delete the character before the cursor, do not yank
+ */
+protected void
+c_delbefore1(EditLine *el)
+{
+	char *cp;
+
+	for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
+		*cp = cp[1];
+
+	el->el_line.lastchar--;
+}
+
+
 /* ce__isword():
  *	Return if p is part of a word according to emacs
  */
 protected int
 ce__isword(int p)
 {
-	return (isalpha((unsigned char)p) || isdigit((unsigned char)p) || strchr("*?_-.[]~=", p) != NULL);
+	return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
 }
 
 
 /* cv__isword():
- *	Return type of word for p according to vi
+ *	Return if p is part of a word according to vi
  */
 protected int
 cv__isword(int p)
 {
-    if (isspace((unsigned char) p))
-        return 0;
-    if ((unsigned char) p == '_' || isalnum((unsigned char) p))
-        return 1;
-    return 2;
+	if (isalnum(p) || p == '_')
+		return 1;
+	if (isgraph(p))
+		return 2;
+	return 0;
 }
 
 
-/* c___isword():
- *	Return if p is part of a space-delimited word (!isspace)
+/* cv__isWord():
+ *	Return if p is part of a big word according to vi
  */
 protected int
-c___isword(p)
-    int p;
+cv__isWord(int p)
 {
-    return !isspace((unsigned char) p);
+	return (!isspace(p));
 }
 
 
@@ -235,7 +286,7 @@
 		 * vi historically deletes with cw only the word preserving the
 		 * trailing whitespace! This is not what 'w' does..
 		 */
-		if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
+		if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
 			while ((p < high) && isspace((unsigned char) *p))
 				p++;
 	}
@@ -252,26 +303,19 @@
  *	Find the previous word vi style
  */
 protected char *
-cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int))
+cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
 {
 	int test;
 
+	p--;
 	while (n--) {
-		p--;
-		/*
-		 * vi historically deletes with cb only the word preserving the
-		 * leading whitespace! This is not what 'b' does..
-		 */
-		if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
-			while ((p > low) && isspace((unsigned char) *p))
-				p--;
+		while ((p > low) && isspace((unsigned char) *p))
+			p--;
 		test = (*wtest)((unsigned char) *p);
 		while ((p >= low) && (*wtest)((unsigned char) *p) == test)
 			p--;
-		p++;
-		while (isspace((unsigned char) *p))
-			p++;
 	}
+	p++;
 
 	/* p now points where we want it */
 	if (p < low)
@@ -322,47 +366,34 @@
 cv_delfini(EditLine *el)
 {
 	int size;
-	int oaction;
+	int action = el->el_chared.c_vcmd.action;
 
-	if (el->el_chared.c_vcmd.action & INSERT)
+	if (action & INSERT)
 		el->el_map.current = el->el_map.key;
 
-	oaction = el->el_chared.c_vcmd.action;
-	el->el_chared.c_vcmd.action = NOP;
-
 	if (el->el_chared.c_vcmd.pos == 0)
+		/* sanity */
 		return;
 
-
-	if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
-		size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
-		c_delbefore(el, size);
-		el->el_line.cursor = el->el_chared.c_vcmd.pos;
-		re_refresh_cursor(el);
-	} else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
-		size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
-		c_delafter(el, size);
-	} else {
+	size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
+	if (size == 0)
 		size = 1;
-		c_delafter(el, size);
-	}
-	switch (oaction) {
-	case DELETE|INSERT:
-		el->el_chared.c_undo.action = DELETE|INSERT;
-		break;
-	case DELETE:
-		el->el_chared.c_undo.action = INSERT;
-		break;
-	case NOP:
-	case INSERT:
-	default:
-		EL_ABORT((el->el_errfile, "Bad oaction %d\n", oaction));
-		break;
+	el->el_line.cursor = el->el_chared.c_vcmd.pos;
+	if (action & YANK) {
+		if (size > 0)
+			cv_yank(el, el->el_line.cursor, size);
+		else
+			cv_yank(el, el->el_line.cursor + size, -size);
+	} else {
+		if (size > 0) {
+			c_delafter(el, size);
+			re_refresh_cursor(el);
+		} else  {
+			c_delbefore(el, -size);
+			el->el_line.cursor += size;
+		}
 	}
-
-
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.dsize = size;
+	el->el_chared.c_vcmd.action = NOP;
 }
 
 
@@ -392,21 +423,19 @@
  *	Go to the end of this word according to vi
  */
 protected char *
-cv__endword(char *p, char *high, int n)
+cv__endword(char *p, char *high, int n, int (*wtest)(int))
 {
+	int test;
+
 	p++;
 
 	while (n--) {
 		while ((p < high) && isspace((unsigned char) *p))
 			p++;
 
-		if (isalnum((unsigned char) *p))
-			while ((p < high) && isalnum((unsigned char) *p))
-				p++;
-		else
-			while ((p < high) && !(isspace((unsigned char) *p) ||
-			    isalnum((unsigned char) *p)))
-				p++;
+		test = (*wtest)((unsigned char) *p);
+		while ((p < high) && (*wtest)((unsigned char) *p) == test)
+			p++;
 	}
 	p--;
 	return (p);
@@ -425,20 +454,23 @@
 	(void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
 	el->el_line.cursor		= el->el_line.buffer;
 	el->el_line.lastchar		= el->el_line.buffer;
-	el->el_line.limit		= &el->el_line.buffer[EL_BUFSIZ - 2];
+	el->el_line.limit		= &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
 
 	el->el_chared.c_undo.buf	= (char *) el_malloc(EL_BUFSIZ);
 	if (el->el_chared.c_undo.buf == NULL)
 		return (-1);
 	(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
-	el->el_chared.c_undo.action	= NOP;
-	el->el_chared.c_undo.isize	= 0;
-	el->el_chared.c_undo.dsize	= 0;
-	el->el_chared.c_undo.ptr	= el->el_line.buffer;
+	el->el_chared.c_undo.len	= -1;
+	el->el_chared.c_undo.cursor	= 0;
+	el->el_chared.c_redo.buf	= (char *) el_malloc(EL_BUFSIZ);
+	if (el->el_chared.c_redo.buf == NULL)
+		return (-1);
+	el->el_chared.c_redo.pos	= el->el_chared.c_redo.buf;
+	el->el_chared.c_redo.lim	= el->el_chared.c_redo.buf + EL_BUFSIZ;
+	el->el_chared.c_redo.cmd	= ED_UNASSIGNED;
 
 	el->el_chared.c_vcmd.action	= NOP;
 	el->el_chared.c_vcmd.pos	= el->el_line.buffer;
-	el->el_chared.c_vcmd.ins	= el->el_line.buffer;
 
 	el->el_chared.c_kill.buf	= (char *) el_malloc(EL_BUFSIZ);
 	if (el->el_chared.c_kill.buf == NULL)
@@ -455,8 +487,8 @@
 	el->el_state.argument		= 1;
 	el->el_state.lastcmd		= ED_UNASSIGNED;
 
-	el->el_chared.c_macro.nline	= NULL;
 	el->el_chared.c_macro.level	= -1;
+	el->el_chared.c_macro.offset	= 0;
 	el->el_chared.c_macro.macro	= (char **) el_malloc(EL_MAXMACRO *
 	    sizeof(char *));
 	if (el->el_chared.c_macro.macro == NULL)
@@ -473,14 +505,11 @@
 	el->el_line.cursor		= el->el_line.buffer;
 	el->el_line.lastchar		= el->el_line.buffer;
 
-	el->el_chared.c_undo.action	= NOP;
-	el->el_chared.c_undo.isize	= 0;
-	el->el_chared.c_undo.dsize	= 0;
-	el->el_chared.c_undo.ptr	= el->el_line.buffer;
+	el->el_chared.c_undo.len	= -1;
+	el->el_chared.c_undo.cursor	= 0;
 
 	el->el_chared.c_vcmd.action	= NOP;
 	el->el_chared.c_vcmd.pos	= el->el_line.buffer;
-	el->el_chared.c_vcmd.ins	= el->el_line.buffer;
 
 	el->el_chared.c_kill.mark	= el->el_line.buffer;
 
@@ -535,7 +564,8 @@
 	el->el_line.buffer = newbuffer;
 	el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
 	el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
-	el->el_line.limit  = &newbuffer[newsz - EL_LEAVE];
+	/* don't set new size until all buffers are enlarged */
+	el->el_line.limit  = &newbuffer[sz - EL_LEAVE];
 
 	/*
 	 * Reallocate kill buffer.
@@ -564,14 +594,22 @@
 
 	/* zero the newly added memory, leave old data in */
 	(void) memset(&newbuffer[sz], 0, newsz - sz);
-
-	el->el_chared.c_undo.ptr = el->el_line.buffer +
-				    (el->el_chared.c_undo.ptr - oldbuf);
 	el->el_chared.c_undo.buf = newbuffer;
+
+	newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
+	if (!newbuffer)
+		return 0;
+	el->el_chared.c_redo.pos = newbuffer +
+			(el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
+	el->el_chared.c_redo.lim = newbuffer +
+			(el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
+	el->el_chared.c_redo.buf = newbuffer;
 	
 	if (!hist_enlargebuf(el, sz, newsz))
 		return 0;
 
+	/* Safe to set enlarged buffer size */
+	el->el_line.limit  = &el->el_line.buffer[newsz - EL_LEAVE];
 	return 1;
 }
 
@@ -586,6 +624,11 @@
 	el->el_line.limit = NULL;
 	el_free((ptr_t) el->el_chared.c_undo.buf);
 	el->el_chared.c_undo.buf = NULL;
+	el_free((ptr_t) el->el_chared.c_redo.buf);
+	el->el_chared.c_redo.buf = NULL;
+	el->el_chared.c_redo.pos = NULL;
+	el->el_chared.c_redo.lim = NULL;
+	el->el_chared.c_redo.cmd = ED_UNASSIGNED;
 	el_free((ptr_t) el->el_chared.c_kill.buf);
 	el->el_chared.c_kill.buf = NULL;
 	el_free((ptr_t) el->el_chared.c_macro.macro);
@@ -638,51 +681,64 @@
  *	Get a string
  */
 protected int
-c_gets(EditLine *el, char *buf)
+c_gets(EditLine *el, char *buf, const char *prompt)
 {
 	char ch;
-	int len = 0;
+	int len;
+	char *cp = el->el_line.buffer;
+
+	if (prompt) {
+		len = strlen(prompt);
+		memcpy(cp, prompt, len + 0u);
+		cp += len;
+	}
+	len = 0;
+
+	for (;;) {
+		el->el_line.cursor = cp;
+		*cp = ' ';
+		el->el_line.lastchar = cp + 1;
+		re_refresh(el);
+
+		if (el_getc(el, &ch) != 1) {
+			ed_end_of_file(el, 0);
+			len = -1;
+			break;
+		}
 
-	for (ch = 0; ch == 0;) {
-		if (el_getc(el, &ch) != 1)
-			return (ed_end_of_file(el, 0));
 		switch (ch) {
-		case '\010':	/* Delete and backspace */
-		case '\177':
-			if (len > 1) {
-				*el->el_line.cursor-- = '\0';
-				el->el_line.lastchar = el->el_line.cursor;
-				buf[len--] = '\0';
-			} else {
-				el->el_line.buffer[0] = '\0';
-				el->el_line.lastchar = el->el_line.buffer;
-				el->el_line.cursor = el->el_line.buffer;
-				return (CC_REFRESH);
+
+		case 0010:	/* Delete and backspace */
+		case 0177:
+			if (len <= 0) {
+				len = -1;
+				break;
 			}
-			re_refresh(el);
-			ch = 0;
-			break;
+			cp--;
+			continue;
 
-		case '\033':	/* ESC */
+		case 0033:	/* ESC */
 		case '\r':	/* Newline */
 		case '\n':
+			buf[len] = ch;
 			break;
 
 		default:
-			if (len >= EL_BUFSIZ)
+			if (len >= EL_BUFSIZ - 16)
 				term_beep(el);
 			else {
 				buf[len++] = ch;
-				*el->el_line.cursor++ = ch;
-				el->el_line.lastchar = el->el_line.cursor;
+				*cp++ = ch;
 			}
-			re_refresh(el);
-			ch = 0;
-			break;
+			continue;
 		}
+		break;
 	}
-	buf[len] = ch;
-	return (len);
+
+	el->el_line.buffer[0] = '\0';
+	el->el_line.lastchar = el->el_line.buffer;
+	el->el_line.cursor = el->el_line.buffer;
+	return len;
 }
 
 
diff --exclude=CVS -ruN src.orig/lib/libedit/chared.h src/lib/libedit/chared.h
--- src.orig/lib/libedit/chared.h	Wed Jan  1 11:48:44 2003
+++ src/lib/libedit/chared.h	Wed Mar 30 20:34:22 2005
@@ -1,3 +1,4 @@
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +14,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)chared.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: chared.h,v 1.5 2000/09/04 22:06:29 lukem Exp $
- * $FreeBSD: src/lib/libedit/chared.h,v 1.6 2003/01/01 18:48:44 schweikh Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -52,7 +48,7 @@
 #define	EL_MAXMACRO	10
 
 /*
- * This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works
+ * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works
  * like real vi: i.e. the transition from command<->insert modes moves
  * the cursor.
  *
@@ -66,28 +62,36 @@
 
 typedef struct c_macro_t {
 	int	  level;
+	int	  offset;
 	char	**macro;
-	char	 *nline;
 } c_macro_t;
 
 /*
- * Undo information for both vi and emacs
+ * Undo information for vi - no undo in emacs (yet)
  */
 typedef struct c_undo_t {
-	int	 action;
-	size_t	 isize;
-	size_t	 dsize;
-	char	*ptr;
-	char	*buf;
+	int	 len;			/* length of saved line */
+	int	 cursor;		/* position of saved cursor */
+	char	*buf;			/* full saved text */
 } c_undo_t;
 
+/* redo for vi */
+typedef struct c_redo_t {
+	char	*buf;			/* redo insert key sequence */
+	char	*pos;
+	char	*lim;
+	el_action_t	cmd;		/* command to redo */
+	char	ch;			/* char that invoked it */
+	int	count;
+	int	action;			/* from cv_action() */
+} c_redo_t;
+
 /*
  * Current action information for vi
  */
 typedef struct c_vcmd_t {
 	int	 action;
 	char	*pos;
-	char	*ins;
 } c_vcmd_t;
 
 /*
@@ -106,6 +110,7 @@
 typedef struct el_chared_t {
 	c_undo_t	c_undo;
 	c_kill_t	c_kill;
+	c_redo_t	c_redo;
 	c_vcmd_t	c_vcmd;
 	c_macro_t	c_macro;
 } el_chared_t;
@@ -120,10 +125,10 @@
 #define	NOP		0x00
 #define	DELETE		0x01
 #define	INSERT		0x02
-#define	CHANGE		0x04
+#define	YANK		0x04
 
-#define	CHAR_FWD	0
-#define	CHAR_BACK	1
+#define	CHAR_FWD	(+1)
+#define	CHAR_BACK	(-1)
 
 #define	MODE_INSERT	0
 #define	MODE_REPLACE	1
@@ -137,19 +142,22 @@
 
 
 protected int	 cv__isword(int);
+protected int	 cv__isWord(int);
 protected void	 cv_delfini(EditLine *);
-protected char	*cv__endword(char *, char *, int);
+protected char	*cv__endword(char *, char *, int, int (*)(int));
 protected int	 ce__isword(int);
-protected int	 c___isword(int);
-protected void	 cv_undo(EditLine *, int, size_t, char *);
+protected void	 cv_undo(EditLine *);
+protected void	 cv_yank(EditLine *, const char *, int);
 protected char	*cv_next_word(EditLine*, char *, char *, int, int (*)(int));
-protected char	*cv_prev_word(EditLine*, char *, char *, int, int (*)(int));
+protected char	*cv_prev_word(char *, char *, int, int (*)(int));
 protected char	*c__next_word(char *, char *, int, int (*)(int));
 protected char	*c__prev_word(char *, char *, int, int (*)(int));
 protected void	 c_insert(EditLine *, int);
 protected void	 c_delbefore(EditLine *, int);
+protected void	 c_delbefore1(EditLine *);
 protected void	 c_delafter(EditLine *, int);
-protected int	 c_gets(EditLine *, char *);
+protected void	 c_delafter1(EditLine *);
+protected int	 c_gets(EditLine *, char *, const char *);
 protected int	 c_hpos(EditLine *);
 
 protected int	 ch_init(EditLine *);
diff --exclude=CVS -ruN src.orig/lib/libedit/common.c src/lib/libedit/common.c
--- src.orig/lib/libedit/common.c	Wed Jan  1 11:48:44 2003
+++ src/lib/libedit/common.c	Thu Mar 31 17:56:24 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: common.c,v 1.9 2000/09/04 22:06:29 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/common.c,v 1.9 2003/01/01 18:48:44 schweikh Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * common.c: Common Editor functions
  */
-#include "sys.h"
 #include "el.h"
 
 /* ed_end_of_file():
@@ -54,7 +53,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_end_of_file(EditLine *el, int c)
+ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	re_goto_bottom(el);
@@ -70,7 +69,7 @@
 protected el_action_t
 ed_insert(EditLine *el, int c)
 {
-	int i;
+	int count = el->el_state.argument;
 
 	if (c == '\0')
 		return (CC_ERROR);
@@ -78,46 +77,28 @@
 	if (el->el_line.lastchar + el->el_state.argument >=
 	    el->el_line.limit) {
 		/* end of buffer space, try to allocate more */
-		if (!ch_enlargebufs(el, (size_t) el->el_state.argument))
+		if (!ch_enlargebufs(el, (size_t) count))
 			return CC_ERROR;	/* error allocating more */
 	}
 
-	if (el->el_state.argument == 1) {
-		if (el->el_state.inputmode != MODE_INSERT) {
-			el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
-			    *el->el_line.cursor;
-			el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
-			    '\0';
-			c_delafter(el, 1);
-		}
-		c_insert(el, 1);
+	if (count == 1) {
+		if (el->el_state.inputmode == MODE_INSERT
+		    || el->el_line.cursor >= el->el_line.lastchar)
+			c_insert(el, 1);
 
 		*el->el_line.cursor++ = c;
-		el->el_state.doingarg = 0;	/* just in case */
 		re_fastaddc(el);		/* fast refresh for one char. */
 	} else {
-		if (el->el_state.inputmode != MODE_INSERT) {
-			for (i = 0; i < el->el_state.argument; i++)
-				el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
-				    el->el_line.cursor[i];
-
-			el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
-			    '\0';
-			c_delafter(el, el->el_state.argument);
-		}
-		c_insert(el, el->el_state.argument);
+		if (el->el_state.inputmode != MODE_REPLACE_1)
+			c_insert(el, el->el_state.argument);
 
-		while (el->el_state.argument--)
+		while (count-- && el->el_line.cursor < el->el_line.lastchar)
 			*el->el_line.cursor++ = c;
 		re_refresh(el);
 	}
 
-	if (el->el_state.inputmode == MODE_REPLACE_1
-	    || el->el_state.inputmode == MODE_REPLACE)
-		el->el_chared.c_undo.action=CHANGE;
- 
 	if (el->el_state.inputmode == MODE_REPLACE_1)
-		return (vi_command_mode(el, 0));
+		return vi_command_mode(el, 0);
 
 	return (CC_NORM);
 }
@@ -129,7 +110,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_prev_word(EditLine *el, int c)
+ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *p, *kp;
 
@@ -157,7 +138,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_next_char(EditLine *el, int c)
+ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 #ifdef notdef			/* XXX */
 #define	EL	el->el_line
@@ -175,7 +156,7 @@
 				return (CC_ERROR);
 #else
 				term_overwrite(el, STReof, 4);
-					/* then do an EOF */
+					/* then do a EOF */
 				term__flush();
 				return (CC_EOF);
 #endif
@@ -208,7 +189,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_kill_line(EditLine *el, int c)
+ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -229,7 +210,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_move_to_end(EditLine *el, int c)
+ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.lastchar;
@@ -237,7 +218,7 @@
 #ifdef VI_MOVE
 		el->el_line.cursor--;
 #endif
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -252,7 +233,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_move_to_beg(EditLine *el, int c)
+ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.buffer;
@@ -261,7 +242,7 @@
 			/* We want FIRST non space character */
 		while (isspace((unsigned char) *el->el_line.cursor))
 			el->el_line.cursor++;
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -301,18 +282,22 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_char(EditLine *el, int c)
+ed_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
+	char *lim = el->el_line.lastchar;
 
-	if (el->el_line.cursor >= el->el_line.lastchar)
+	if (el->el_line.cursor >= lim ||
+	    (el->el_line.cursor == lim - 1 &&
+	    el->el_map.type == MAP_VI &&
+	    el->el_chared.c_vcmd.action == NOP))
 		return (CC_ERROR);
 
 	el->el_line.cursor += el->el_state.argument;
-	if (el->el_line.cursor > el->el_line.lastchar)
-		el->el_line.cursor = el->el_line.lastchar;
+	if (el->el_line.cursor > lim)
+		el->el_line.cursor = lim;
 
 	if (el->el_map.type == MAP_VI)
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -326,7 +311,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_word(EditLine *el, int c)
+ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
@@ -338,7 +323,7 @@
 	    ce__isword);
 
 	if (el->el_map.type == MAP_VI)
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -352,7 +337,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_char(EditLine *el, int c)
+ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor > el->el_line.buffer) {
@@ -361,7 +346,7 @@
 			el->el_line.cursor = el->el_line.buffer;
 
 		if (el->el_map.type == MAP_VI)
-			if (el->el_chared.c_vcmd.action & DELETE) {
+			if (el->el_chared.c_vcmd.action != NOP) {
 				cv_delfini(el);
 				return (CC_REFRESH);
 			}
@@ -399,7 +384,7 @@
 ed_digit(EditLine *el, int c)
 {
 
-	if (!isdigit((unsigned char) c))
+	if (!isdigit(c))
 		return (CC_ERROR);
 
 	if (el->el_state.doingarg) {
@@ -413,25 +398,9 @@
 			    (el->el_state.argument * 10) + (c - '0');
 		}
 		return (CC_ARGHACK);
-	} else {
-		if (el->el_line.lastchar + 1 >= el->el_line.limit) {
-			if (!ch_enlargebufs(el, 1))
-				return (CC_ERROR);
-		}
-
-		if (el->el_state.inputmode != MODE_INSERT) {
-			el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
-			    *el->el_line.cursor;
-			el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
-			    '\0';
-			c_delafter(el, 1);
-		}
-		c_insert(el, 1);
-		*el->el_line.cursor++ = c;
-		el->el_state.doingarg = 0;
-		re_fastaddc(el);
 	}
-	return (CC_NORM);
+
+	return ed_insert(el, c);
 }
 
 
@@ -443,7 +412,7 @@
 ed_argument_digit(EditLine *el, int c)
 {
 
-	if (!isdigit((unsigned char) c))
+	if (!isdigit(c))
 		return (CC_ERROR);
 
 	if (el->el_state.doingarg) {
@@ -465,12 +434,10 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_unassigned(EditLine *el, int c)
+ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
 {
 
-	term_beep(el);
-	term__flush();
-	return (CC_NORM);
+	return (CC_ERROR);
 }
 
 
@@ -484,7 +451,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigint(EditLine *el, int c)
+ed_tty_sigint(EditLine *el __attribute__((__unused__)), 
+	      int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -497,7 +465,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_dsusp(EditLine *el, int c)
+ed_tty_dsusp(EditLine *el __attribute__((__unused__)), 
+	     int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -510,7 +479,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_flush_output(EditLine *el, int c)
+ed_tty_flush_output(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -523,7 +493,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigquit(EditLine *el, int c)
+ed_tty_sigquit(EditLine *el __attribute__((__unused__)), 
+	       int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -536,7 +507,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigtstp(EditLine *el, int c)
+ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), 
+	       int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -549,7 +521,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_stop_output(EditLine *el, int c)
+ed_tty_stop_output(EditLine *el __attribute__((__unused__)), 
+		   int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -562,7 +535,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_start_output(EditLine *el, int c)
+ed_tty_start_output(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -575,14 +549,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_newline(EditLine *el, int c)
+ed_newline(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	re_goto_bottom(el);
 	*el->el_line.lastchar++ = '\n';
 	*el->el_line.lastchar = '\0';
-	if (el->el_map.type == MAP_VI)
-		el->el_chared.c_vcmd.ins = el->el_line.buffer;
 	return (CC_NEWLINE);
 }
 
@@ -593,7 +565,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_prev_char(EditLine *el, int c)
+ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor <= el->el_line.buffer)
@@ -613,7 +585,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_clear_screen(EditLine *el, int c)
+ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	term_clear_screen(el);	/* clear the whole real screen */
@@ -628,7 +600,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_redisplay(EditLine *el, int c)
+ed_redisplay(EditLine *el __attribute__((__unused__)), 
+	     int c __attribute__((__unused__)))
 {
 
 	return (CC_REDISPLAY);
@@ -641,7 +614,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_start_over(EditLine *el, int c)
+ed_start_over(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	ch_reset(el);
@@ -655,7 +628,8 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_sequence_lead_in(EditLine *el, int c)
+ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -668,11 +642,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_history(EditLine *el, int c)
+ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	char beep = 0;
+	int sv_event = el->el_history.eventno;
 
-	el->el_chared.c_undo.action = NOP;
+	el->el_chared.c_undo.len = -1;
 	*el->el_line.lastchar = '\0';		/* just in case */
 
 	if (el->el_history.eventno == 0) {	/* save the current buffer
@@ -685,15 +660,17 @@
 	el->el_history.eventno += el->el_state.argument;
 
 	if (hist_get(el) == CC_ERROR) {
+		if (el->el_map.type == MAP_VI) {
+			el->el_history.eventno = sv_event;
+			return CC_ERROR;
+		}
 		beep = 1;
 		/* el->el_history.eventno was fixed by first call */
 		(void) hist_get(el);
 	}
-	re_refresh(el);
 	if (beep)
-		return (CC_ERROR);
-	else
-		return (CC_NORM);	/* was CC_UP_HIST */
+		return CC_REFRESH_BEEP;
+	return CC_REFRESH;
 }
 
 
@@ -703,19 +680,24 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_history(EditLine *el, int c)
+ed_next_history(EditLine *el, int c __attribute__((__unused__)))
 {
+	el_action_t beep = CC_REFRESH, rval;
 
-	el->el_chared.c_undo.action = NOP;
+	el->el_chared.c_undo.len = -1;
 	*el->el_line.lastchar = '\0';	/* just in case */
 
 	el->el_history.eventno -= el->el_state.argument;
 
 	if (el->el_history.eventno < 0) {
 		el->el_history.eventno = 0;
-		return (CC_ERROR);/* make it beep */
+		beep = CC_REFRESH_BEEP;
 	}
-	return (hist_get(el));
+	rval = hist_get(el);
+	if (rval == CC_REFRESH)
+		return beep;
+	return rval;
+
 }
 
 
@@ -725,14 +707,14 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_search_prev_history(EditLine *el, int c)
+ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	const char *hp;
 	int h;
 	bool_t found = 0;
 
 	el->el_chared.c_vcmd.action = NOP;
-	el->el_chared.c_undo.action = NOP;
+	el->el_chared.c_undo.len = -1;
 	*el->el_line.lastchar = '\0';	/* just in case */
 	if (el->el_history.eventno < 0) {
 #ifdef DEBUG_EDIT
@@ -793,14 +775,14 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_search_next_history(EditLine *el, int c)
+ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	const char *hp;
 	int h;
 	bool_t found = 0;
 
 	el->el_chared.c_vcmd.action = NOP;
-	el->el_chared.c_undo.action = NOP;
+	el->el_chared.c_undo.len = -1;
 	*el->el_line.lastchar = '\0';	/* just in case */
 
 	if (el->el_history.eventno == 0)
@@ -847,7 +829,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_line(EditLine *el, int c)
+ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *ptr;
 	int nchars = c_hpos(el);
@@ -890,7 +872,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_line(EditLine *el, int c)
+ed_next_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *ptr;
 	int nchars = c_hpos(el);
@@ -924,30 +906,18 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_command(EditLine *el, int c)
+ed_command(EditLine *el, int c __attribute__((__unused__)))
 {
 	char tmpbuf[EL_BUFSIZ];
 	int tmplen;
 
-	el->el_line.buffer[0] = '\0';
-	el->el_line.lastchar = el->el_line.buffer;
-	el->el_line.cursor = el->el_line.buffer;
-
-	c_insert(el, 3);	/* prompt + ": " */
-	*el->el_line.cursor++ = '\n';
-	*el->el_line.cursor++ = ':';
-	*el->el_line.cursor++ = ' ';
-	re_refresh(el);
+	tmplen = c_gets(el, tmpbuf, "\n: ");
+	term__putc('\n');
 
-	tmplen = c_gets(el, tmpbuf);
-	tmpbuf[tmplen] = '\0';
-
-	el->el_line.buffer[0] = '\0';
-	el->el_line.lastchar = el->el_line.buffer;
-	el->el_line.cursor = el->el_line.buffer;
+	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
+		term_beep(el);
 
-	if (parse_line(el, tmpbuf) == -1)
-		return (CC_ERROR);
-	else
-		return (CC_REFRESH);
+	el->el_map.current = el->el_map.key;
+	re_clear_display(el);
+	return CC_REFRESH;
 }
diff --exclude=CVS -ruN src.orig/lib/libedit/config.h src/lib/libedit/config.h
--- src.orig/lib/libedit/config.h	Wed Dec 31 17:00:00 1969
+++ src/lib/libedit/config.h	Wed Mar 30 20:57:21 2005
@@ -0,0 +1,18 @@
+/* config.h.  Generated automatically by configure.  */
+/* #undef SUNOS */
+
+#define HAVE_SYS_CDEFS_H 1
+#define HAVE_TERMCAP_H 1
+/* #undef HAVE_CURSES_H */
+/* #undef HAVE_NCURSES_H */
+/* #undef HAVE_TERM_H */
+#define HAVE_VIS_H 1
+#define HAVE_ISSETUGID 1
+
+#define HAVE_STRLCAT 1
+#define HAVE_STRLCPY 1
+#define HAVE_FGETLN 1
+#define HAVE_STRVIS 1
+#define HAVE_STRUNVIS 1
+
+#include "sys.h"
diff --exclude=CVS -ruN src.orig/lib/libedit/editline.3 src/lib/libedit/editline.3
--- src.orig/lib/libedit/editline.3	Sun Feb 13 16:45:47 2005
+++ src/lib/libedit/editline.3	Wed Mar 30 21:00:50 2005
@@ -1,6 +1,6 @@
-.\"	$NetBSD: editline.3,v 1.20 2000/02/28 17:41:05 chopps Exp $
+.\"	$NetBSD: editline.3,v 1.46 2005/03/19 17:36:02 christos Exp $
 .\"
-.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
@@ -13,11 +13,7 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"        This product includes software developed by the NetBSD
-.\"        Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" 3. Neither the name of The NetBSD Foundation nor the names of its
 .\"    contributors may be used to endorse or promote products derived
 .\"    from this software without specific prior written permission.
 .\"
@@ -33,9 +29,9 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libedit/editline.3,v 1.23 2005/02/13 23:45:47 ru Exp $
+.\" $FreeBSD$
 .\"
-.Dd November 12, 1999
+.Dd March 19, 2005
 .Os
 .Dt EDITLINE 3
 .Sh NAME
@@ -55,8 +51,13 @@
 .Nm el_deletestr ,
 .Nm history_init ,
 .Nm history_end ,
-.Nm history
-.Nd line editor and history functions
+.Nm history ,
+.Nm tok_init ,
+.Nm tok_end ,
+.Nm tok_reset ,
+.Nm tok_line ,
+.Nm tok_str
+.Nd line editor, history and tokenization functions
 .Sh LIBRARY
 .Lb libedit
 .Sh SYNOPSIS
@@ -74,7 +75,7 @@
 .Ft void
 .Fn el_push "EditLine *e" "const char *str"
 .Ft int
-.Fn el_parse "EditLine *e" "int argc" "char *argv[]"
+.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
 .Ft int
 .Fn el_set "EditLine *e" "int op" "..."
 .Ft int
@@ -95,10 +96,20 @@
 .Fn history_end "History *h"
 .Ft int
 .Fn history "History *h" "HistEvent *ev" "int op" "..."
+.Ft Tokenizer *
+.Fn tok_init "const char *IFS"
+.Ft void
+.Fn tok_end "Tokenizer *t"
+.Ft void
+.Fn tok_reset "Tokenizer *t"
+.Ft int
+.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
+.Ft int
+.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
 .Sh DESCRIPTION
 The
 .Nm
-library provides generic line editing and history functions,
+library provides generic line editing, history and tokenization functions,
 similar to those found in
 .Xr sh 1 .
 .Pp
@@ -154,7 +165,7 @@
 Read a character from the tty.
 .Fa ch
 is modified to contain the character read.
-Returns the number of characters read if successful, -1 otherwise.
+Returns the number of characters read if successful, \-1 otherwise.
 .It Fn el_push
 Pushes
 .Fa str
@@ -176,7 +187,7 @@
 .Nm
 commands.
 If the command is prefixed with
-.Dq prog:
+.Dq prog :
 then
 .Fn el_parse
 will only execute the command if
@@ -186,10 +197,10 @@
 argument supplied to
 .Fn el_init .
 The return value is
--1 if the command is unknown,
+\-1 if the command is unknown,
 0 if there was no error or
 .Dq prog
-did not match, or
+didn't match, or
 1 if the command returned an error.
 Refer to
 .Xr editrc 5
@@ -305,7 +316,7 @@
 .It Dv EL_ADDFN , Xo
 .Fa "const char *name" ,
 .Fa "const char *help" ,
-.Fa "unsigned char (*func)(EditLine *e, int ch)
+.Fa "unsigned char (*func)(EditLine *e, int ch)"
 .Xc
 Add a user defined function,
 .Fn func ,
@@ -370,6 +381,24 @@
 (using
 .Fn el_get )
 to determine if editing should be enabled or not.
+.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
+Define the character reading function as
+.Fa f ,
+which is to return the number of characters read and store them in
+.Fa c .
+This function is called internally by
+.Fn el_gets
+and
+.Fn el_getc .
+The builtin function can be set or restored with the special function
+name ``EL_BUILTIN_GETCFN''.
+.It Dv EL_CLIENTDATA , Fa "void *data"
+Register
+.Fa data
+to be associated with this EditLine structure.
+It can be retrieved with the corresponding
+.Fn el_get
+call.
 .El
 .It Fn el_get
 Get
@@ -378,6 +407,7 @@
 .Fa op
 determines which parameter to retrieve into
 .Fa result .
+Returns 0 if successful, \-1 otherwise.
 .Pp
 The following values for
 .Fa op
@@ -401,6 +431,22 @@
 above).
 .It Dv EL_EDITMODE, Fa "int *"
 Return non-zero if editing is enabled.
+.It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)"
+Return a pointer to the function that read characters, which is equal to
+``EL_BUILTIN_GETCFN'' in the case of the default builtin function.
+.It Dv EL_CLIENTDATA , Fa "void **data"
+Retrieve
+.Fa data
+previously registered with the corresponding
+.Fn el_set
+call.
+.It Dv EL_UNBUFFERED, Fa "int"
+Sets or clears unbuffered mode.
+In this mode,
+.Fn el_gets
+will return immediately after processing a single character.
+.It Dv EL_PREP_TERM, Fa "int"
+Sets or clears terminal editing mode.
 .El
 .It Fn el_source
 Initialise
@@ -429,7 +475,7 @@
 has been set with
 .Fn el_set ,
 then this is done automatically.
-Otherwise, it is the responsibility of the application to call
+Otherwise, it's the responsibility of the application to call
 .Fn el_resize
 on the appropriate occasions.
 .It Fn el_line
@@ -443,13 +489,23 @@
     const char *lastchar;  /* address of last character */
 } LineInfo;
 .Ed
+.Pp
+.Fa buffer
+is not NUL terminated.
+This function may be called after
+.Fn el_gets
+to obtain the
+.Fa LineInfo
+structure pertaining to line returned by that function,
+and from within user defined functions added with
+.Dv EL_ADDFN .
 .It Fn el_insertstr
 Insert
 .Fa str
 into the line at the cursor.
-Returns -1 if
+Returns \-1 if
 .Fa str
-is empty or will not fit, and 0 otherwise.
+is empty or won't fit, and 0 otherwise.
 .It Fn el_deletestr
 Delete
 .Fa num
@@ -511,7 +567,7 @@
 .Xc
 Define functions to perform various history operations.
 .Fa ptr
-is the argument given to a function when it is invoked.
+is the argument given to a function when it's invoked.
 .It Dv H_FIRST
 Return the first element in the history.
 .It Dv H_LAST
@@ -527,7 +583,11 @@
 .It Dv H_ADD , Fa "const char *str"
 Append
 .Fa str
-to the current element of the history, or create an element with
+to the current element of the history, or perform the
+.Dv H_ENTER
+operation with argument
+.Fa str
+if there is no current element.
 .It Dv H_APPEND , Fa "const char *str"
 Append
 .Fa str
@@ -537,6 +597,17 @@
 .Fa str
 as a new element to the history, and, if necessary,
 removing the oldest entry to keep the list to the created size.
+If
+.Dv H_SETUNIQUE
+was has been called with a non-zero arguments, the element
+will not be entered into the history if its contents match
+the ones of the current history element.
+If the element is entered
+.Fn history
+returns 1, if it is ignored as a duplicate returns 0.
+Finally
+.Fn history
+returns \-1 if an error occurred.
 .It Dv H_PREV_STR , Fa "const char *str"
 Return the closest previous event that starts with
 .Fa str .
@@ -555,17 +626,94 @@
 .It Dv H_SAVE , Fa "const char *file"
 Save the history list to
 .Fa file .
+.It Dv H_SETUNIQUE , Fa "int unique"
+Set if the adjacent identical event strings should not be entered into
+the history.
+.It Dv H_GETUNIQUE
+Retrieve the current setting if if adjacent elements should be entered into
+the history.
 .El
 .Pp
-The
 .Fn history
-function returns 0 if the operation
+returns \*[Gt]= 0 if the operation
 .Fa op
 succeeds.
 Otherwise, \-1 is returned and
 .Fa ev
 is updated to contain more details about the error.
 .El
+.Sh TOKENIZATION FUNCTIONS
+The tokenization functions use a common data structure,
+.Fa Tokenizer ,
+which is created by
+.Fn tok_init
+and freed by
+.Fn tok_end .
+.Pp
+The following functions are available:
+.Bl -tag -width 4n
+.It Fn tok_init
+Initialise the tokenizer, and return a data structure
+to be used by all other tokenizer functions.
+.Fa IFS
+contains the Input Field Separators, which defaults to
+.Aq space ,
+.Aq tab ,
+and
+.Aq newline
+if
+.Dv NULL .
+.It Fn tok_end
+Clean up and finish with
+.Fa t ,
+assumed to have been created with
+.Fn tok_init .
+.It Fn tok_reset
+Reset the tokenizer state.
+Use after a line has been successfully tokenized
+by
+.Fn tok_line
+or
+.Fn tok_str
+and before a new line is to be tokenized.
+.It Fn tok_line
+Tokenize
+.Fa li ,
+If successful, modify:
+.Fa argv
+to contain the words,
+.Fa argc
+to contain the number of words,
+.Fa cursorc
+(if not
+.Dv NULL )
+to contain the index of the word containing the cursor,
+and
+.Fa cursoro
+(if not
+.Dv NULL )
+to contain the offset within
+.Fa argv[cursorc]
+of the cursor.
+.Pp
+Returns
+0 if successful,
+\-1 for an internal error,
+1 for an unmatched single quote,
+2 for an unmatched double quote,
+and
+3 for a backslash quoted
+.Aq newline .
+A positive exit code indicates that another line should be read
+and tokenization attempted again.
+.
+.It Fn tok_str
+A simpler form of
+.Fn tok_line ;
+.Fa str
+is a NUL terminated string to tokenize.
+.El
+.
 .\"XXX.Sh EXAMPLES
 .\"XXX: provide some examples
 .Sh SEE ALSO
@@ -581,31 +729,25 @@
 .Dv CC_REDISPLAY
 appeared in
 .Nx 1.3 .
-.Dv CC_REFRESH_BEEP
-and
+.Dv CC_REFRESH_BEEP ,
 .Dv EL_EDITMODE
-appeared in
+and the readline emulation appeared in
 .Nx 1.4 .
 .Dv EL_RPROMPT
 appeared in
 .Nx 1.5 .
 .Sh AUTHORS
-.An -nosplit
 The
 .Nm
-library was written by
-.An Christos Zoulas .
-.An Luke Mewburn
-wrote this manual and implemented
+library was written by Christos Zoulas.
+Luke Mewburn wrote this manual and implemented
 .Dv CC_REDISPLAY ,
 .Dv CC_REFRESH_BEEP ,
 .Dv EL_EDITMODE ,
 and
 .Dv EL_RPROMPT .
+Jaromir Dolecek implemented the readline emulation.
 .Sh BUGS
-The tokenization functions are not publically defined in
-.In histedit.h .
-.Pp
 At this time, it is the responsibility of the caller to
 check the result of the
 .Dv EL_EDITMODE
diff --exclude=CVS -ruN src.orig/lib/libedit/editrc.5 src/lib/libedit/editrc.5
--- src.orig/lib/libedit/editrc.5	Sun Feb 13 15:25:13 2005
+++ src/lib/libedit/editrc.5	Wed Mar 30 21:03:14 2005
@@ -1,4 +1,4 @@
-.\"	$NetBSD: editrc.5,v 1.10 2000/11/08 00:09:38 lukem Exp $
+.\"	$NetBSD: editrc.5,v 1.19 2003/11/01 23:35:33 christos Exp $
 .\"
 .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -13,11 +13,7 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"        This product includes software developed by the NetBSD
-.\"        Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" 3. Neither the name of The NetBSD Foundation nor the names of its
 .\"    contributors may be used to endorse or promote products derived
 .\"    from this software without specific prior written permission.
 .\"
@@ -33,9 +29,9 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libedit/editrc.5,v 1.17 2005/02/13 22:25:13 ru Exp $
+.\" $FreeBSD$
 .\"
-.Dd November 8, 2000
+.Dd October 18, 2003
 .Os
 .Dt EDITRC 5
 .Sh NAME
@@ -64,7 +60,7 @@
 .Ar prog
 is the program name string that a program defines when it calls
 .Xr el_init 3
-to setup
+to set up
 .Xr editline 3 ,
 which is usually
 .Va argv[0] .
@@ -165,8 +161,10 @@
 .Sm off
 .Sq No ^ Ar character
 .Sm on
-(e.g.\&
-.Sq ^A ) ,
+.Po
+e.g.
+.Sq ^A
+.Pc ,
 and the following backslashed escape sequences:
 .Pp
 .Bl -tag -compact -offset indent -width 4n
@@ -226,12 +224,28 @@
 causing an error.
 .Fl v
 causes messages to be verbose.
-.It Ic edit Op Cm on | off
+.It Ic edit Op Li on | Li off
 Enable or disable the
 .Nm editline
 functionality in a program.
-.It Ic history
-List the history.
+.It Ic history Ar list | Ar size Dv n | Ar unique Dv n
+The 
+.Ar list
+command lists all entries in the history.
+The
+.Ar size
+command sets the history size to
+.Dv n
+entries.
+The
+.Ar unique
+command controls if history should keep duplicate entries.
+If
+.Dv n
+is non zero, only keep unique history entries.
+If
+.Dv n
+is zero, then keep all entries (the default).
 .It Ic telltc
 List the values of all the terminal capabilities (see
 .Xr termcap 5 ) .
@@ -251,10 +265,11 @@
 .Op Ar +mode
 .Op Ar -mode
 .Op Ar mode
+.Op Ar char=c
 .Xc
 Control which tty modes that
 .Nm
-will not allow the user to change.
+won't allow the user to change.
 .Fl d ,
 .Fl q
 or
@@ -272,9 +287,13 @@
 Without other arguments,
 .Ic setty
 lists the modes in the chosen set which are fixed on
-.Pq Sq +mode
+.Po
+.Sq +mode
+.Pc
 or off
-.Pq Sq -mode .
+.Po
+.Sq -mode
+.Pc .
 .Fl a
 lists all tty modes in the chosen set regardless of the setting.
 With
@@ -287,6 +306,15 @@
 on or off or removes control of
 .Ar mode
 in the chosen set.
+.Pp
+.Ic Setty
+can also be used to set tty characters to particular values using
+.Ar char=value .
+If
+.Ar value
+is empty
+then the character is set to
+.Dv _POSIX_VDISABLE .
 .El
 .Sh EDITOR COMMANDS
 The following editor commands are available for use in key bindings:
@@ -479,12 +507,9 @@
 .Xr regex 3 ,
 .Xr termcap 5
 .Sh AUTHORS
-.An -nosplit
 The
 .Nm editline
-library was written by
-.An Christos Zoulas ,
-and this manual was written by
-.An Luke Mewburn ,
+library was written by Christos Zoulas,
+and this manual was written by Luke Mewburn,
 with some sections inspired by
 .Xr tcsh 1 .
diff --exclude=CVS -ruN src.orig/lib/libedit/el.c src/lib/libedit/el.c
--- src.orig/lib/libedit/el.c	Sun Jun 16 02:29:35 2002
+++ src/lib/libedit/el.c	Thu Mar 31 17:54:20 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,21 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: el.c,v 1.20 2000/11/11 22:18:57 christos Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)el.c	8.2 (Berkeley) 1/3/94";
+#else
+__RCSID("$NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/el.c,v 1.11 2002/06/16 08:29:35 mdodd Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * el.c: EditLine interface functions
  */
-#include "sys.h"
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <string.h>
@@ -62,9 +60,6 @@
 {
 
 	EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
-#ifdef DEBUG
-	char *tty;
-#endif
 
 	if (el == NULL)
 		return (NULL);
@@ -74,14 +69,21 @@
 	el->el_infd = fileno(fin);
 	el->el_outfile = fout;
 	el->el_errfile = ferr;
-	el->el_prog = strdup(prog);
+	if ((el->el_prog = el_strdup(prog)) == NULL) {
+		el_free(el);
+		return NULL;
+	}
 
 	/*
          * Initialize all the modules. Order is important!!!
          */
 	el->el_flags = 0;
 
-	(void) term_init(el);
+	if (term_init(el) == -1) {
+		el_free(el->el_prog);
+		el_free(el);
+		return NULL;
+	}
 	(void) key_init(el);
 	(void) map_init(el);
 	if (tty_init(el) == -1)
@@ -91,7 +93,7 @@
 	(void) hist_init(el);
 	(void) prompt_init(el);
 	(void) sig_init(el);
-	el->data = NULL;
+	(void) read_init(el);
 
 	return (el);
 }
@@ -143,11 +145,12 @@
 el_set(EditLine *el, int op, ...)
 {
 	va_list va;
-	int rv;
-	va_start(va, op);
+	int rv = 0;
 
 	if (el == NULL)
 		return (-1);
+	va_start(va, op);
+
 	switch (op) {
 	case EL_PROMPT:
 	case EL_RPROMPT:
@@ -167,7 +170,6 @@
 			el->el_flags |= HANDLE_SIGNALS;
 		else
 			el->el_flags &= ~HANDLE_SIGNALS;
-		rv = 0;
 		break;
 
 	case EL_BIND:
@@ -176,7 +178,7 @@
 	case EL_ECHOTC:
 	case EL_SETTY:
 	{
-		char *argv[20];
+		const char *argv[20];
 		int i;
 
 		for (i = 1; i < 20; i++)
@@ -244,8 +246,41 @@
 		rv = 0;
 		break;
 
+	case EL_GETCFN:
+	{
+		el_rfunc_t rc = va_arg(va, el_rfunc_t);
+		rv = el_read_setfn(el, rc);
+		break;
+	}
+
+	case EL_CLIENTDATA:
+		el->el_data = va_arg(va, void *);
+		break;
+
+	case EL_UNBUFFERED:
+		rv = va_arg(va, int);
+		if (rv && !(el->el_flags & UNBUFFERED)) {
+			el->el_flags |= UNBUFFERED;
+			read_prepare(el);
+		} else if (!rv && (el->el_flags & UNBUFFERED)) {
+			el->el_flags &= ~UNBUFFERED;
+			read_finish(el);
+		}
+		rv = 0;
+		break;
+
+	case EL_PREP_TERM:
+		rv = va_arg(va, int);
+		if (rv)
+			(void) tty_rawmode(el);
+		else
+			(void) tty_cookedmode(el);
+		rv = 0;
+		break;
+
 	default:
 		rv = -1;
+		break;
 	}
 
 	va_end(va);
@@ -266,11 +301,11 @@
 	switch (op) {
 	case EL_PROMPT:
 	case EL_RPROMPT:
-		rv = prompt_get(el, (el_pfunc_t *) & ret, op);
+		rv = prompt_get(el, (void *) &ret, op);
 		break;
 
 	case EL_EDITOR:
-		rv = map_get_editor(el, (const char **) &ret);
+		rv = map_get_editor(el, (void *) &ret);
 		break;
 
 	case EL_SIGNAL:
@@ -283,21 +318,22 @@
 		rv = 0;
 		break;
 
-#if 0				/* XXX */
 	case EL_TERMINAL:
-		rv = term_get(el, (const char *) &ret);
+		term_get(el, (const char **)ret);
+		rv = 0;
 		break;
 
+#if 0				/* XXX */
 	case EL_BIND:
 	case EL_TELLTC:
 	case EL_SETTC:
 	case EL_ECHOTC:
 	case EL_SETTY:
 	{
-		char *argv[20];
+		const char *argv[20];
 		int i;
 
-		for (i = 1; i < 20; i++)
+ 		for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
 			if ((argv[i] = va_arg(va, char *)) == NULL)
 				break;
 
@@ -354,6 +390,21 @@
 		break;
 #endif /* XXX */
 
+	case EL_GETCFN:
+		*((el_rfunc_t *)ret) = el_read_getfn(el);
+		rv = 0;
+		break;
+
+	case EL_CLIENTDATA:
+		*((void **)ret) = el->el_data;
+		rv = 0;
+		break;
+
+	case EL_UNBUFFERED:
+		*((int *) ret) = (!(el->el_flags & UNBUFFERED));
+		rv = 0;
+		break;
+
 	default:
 		rv = -1;
 	}
@@ -361,30 +412,6 @@
 	return (rv);
 }
 
-/* el_data_get():
- *	Set user private data.
- */
-public void
-el_data_set (el, data)
-    EditLine *el;
-    void *data;
-{
-    el->data = data;
-
-    return;
-}
-
-/* el_data_get():
- *	Return user private data.
- */
-public void *
-el_data_get (el)
-    EditLine *el;
-{
-    if (el->data)
-	return (el->data);
-    return (NULL);
-}
 
 /* el_line():
  *	Return editing info
@@ -396,7 +423,6 @@
 	return (const LineInfo *) (void *) &el->el_line;
 }
 
-static const char elpath[] = "/.editrc";
 
 /* el_source():
  *	Source a file
@@ -406,10 +432,14 @@
 {
 	FILE *fp;
 	size_t len;
-	char *ptr, path[MAXPATHLEN];
+	char *ptr;
 
 	fp = NULL;
 	if (fname == NULL) {
+#ifdef HAVE_ISSETUGID
+		static const char elpath[] = "/.editrc";
+		char path[MAXPATHLEN];
+
 		if (issetugid())
 			return (-1);
 		if ((ptr = getenv("HOME")) == NULL)
@@ -419,6 +449,14 @@
 		if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
 			return (-1);
 		fname = path;
+#else
+		/*
+		 * If issetugid() is missing, always return an error, in order
+		 * to keep from inadvertently opening up the user to a security
+		 * hole.
+		 */
+		return (-1);
+#endif
 	}
 	if (fp == NULL)
 		fp = fopen(fname, "r");
@@ -477,7 +515,7 @@
  */
 protected int
 /*ARGSUSED*/
-el_editmode(EditLine *el, int argc, char **argv)
+el_editmode(EditLine *el, int argc, const char **argv)
 {
 	const char *how;
 
@@ -485,10 +523,13 @@
 		return (-1);
 
 	how = argv[1];
-	if (strcmp(how, "on") == 0)
+	if (strcmp(how, "on") == 0) {
 		el->el_flags &= ~EDIT_DISABLED;
-	else if (strcmp(how, "off") == 0)
+		tty_rawmode(el);
+	} else if (strcmp(how, "off") == 0) {
+		tty_cookedmode(el);
 		el->el_flags |= EDIT_DISABLED;
+	}
 	else {
 		(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
 		return (-1);
diff --exclude=CVS -ruN src.orig/lib/libedit/el.h src/lib/libedit/el.h
--- src.orig/lib/libedit/el.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/el.h	Wed Mar 30 21:04:03 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)el.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: el.h,v 1.7 2000/11/11 22:18:57 christos Exp $
- * $FreeBSD: src/lib/libedit/el.h,v 1.4 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -55,9 +52,10 @@
 
 #define	EL_BUFSIZ	1024		/* Maximum line size		*/
 
-#define	HANDLE_SIGNALS	1<<0
-#define	NO_TTY		1<<1
-#define	EDIT_DISABLED	1<<2
+#define	HANDLE_SIGNALS	0x01
+#define	NO_TTY		0x02
+#define	EDIT_DISABLED	0x04
+#define	UNBUFFERED	0x08
 
 typedef int bool_t;			/* True or not			*/
 
@@ -72,7 +70,7 @@
 	char	*buffer;		/* Input line			*/
 	char	*cursor;		/* Cursor position		*/
 	char	*lastchar;		/* Last character		*/
-	const char	*limit;			/* Max position			*/
+	const char	*limit;		/* Max position			*/
 } el_line_t;
 
 /*
@@ -84,14 +82,16 @@
 	int		argument;	/* Numeric argument		*/
 	int		metanext;	/* Is the next char a meta char */
 	el_action_t	lastcmd;	/* Previous command		*/
+	el_action_t	thiscmd;	/* this command 		*/
+	char		thisch;		/* char that generated it	*/
 } el_state_t;
 
 /*
  * Until we come up with something better...
  */
+#define	el_strdup(a)	strdup(a)
 #define	el_malloc(a)	malloc(a)
 #define	el_realloc(a,b)	realloc(a, b)
-#define el_reallocf(a,b) reallocf(a, b)
 #define	el_free(a)	free(a)
 
 #include "tty.h"
@@ -107,6 +107,7 @@
 #include "parse.h"
 #include "sig.h"
 #include "help.h"
+#include "read.h"
 
 struct editline {
 	char		 *el_prog;	/* the program name		*/
@@ -117,6 +118,7 @@
 	coord_t		  el_cursor;	/* Cursor location		*/
 	char		**el_display;	/* Real screen image = what is there */
 	char		**el_vdisplay;	/* Virtual screen image = what we see */
+	void		 *el_data;	/* Client data			*/
 	el_line_t	  el_line;	/* The current line information	*/
 	el_state_t	  el_state;	/* Current editor state		*/
 	el_term_t	  el_term;	/* Terminal dependent stuff	*/
@@ -130,15 +132,18 @@
 	el_history_t	  el_history;	/* History stuff		*/
 	el_search_t	  el_search;	/* Search stuff			*/
 	el_signal_t	  el_signal;	/* Signal handling stuff	*/
-
-	void		 *data;		/* user data */
+	el_read_t	  el_read;	/* Character reading stuff	*/
 };
 
-protected int	el_editmode(EditLine *, int, char **);
+protected int	el_editmode(EditLine *, int, const char **);
 
 #ifdef DEBUG
-#define EL_ABORT(a)	(void) (fprintf(el->el_errfile, "%s, %d: ", \
-				__FILE__, __LINE__), fprintf a, abort())
+#define	EL_ABORT(a)	do { \
+				fprintf(el->el_errfile, "%s, %d: ", \
+					 __FILE__, __LINE__); \
+				fprintf a; \
+				abort(); \
+			} while( /*CONSTCOND*/0);
 #else
 #define EL_ABORT(a)	abort()
 #endif
diff --exclude=CVS -ruN src.orig/lib/libedit/emacs.c src/lib/libedit/emacs.c
--- src.orig/lib/libedit/emacs.c	Wed Jan  1 11:48:44 2003
+++ src/lib/libedit/emacs.c	Thu Mar 31 17:54:27 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: emacs.c,v 1.8 2000/09/04 22:06:29 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)emacs.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/emacs.c,v 1.8 2003/01/01 18:48:44 schweikh Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * emacs.c: Emacs functions
  */
-#include "sys.h"
 #include "el.h"
 
 /* em_delete_or_list():
@@ -54,14 +53,14 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_delete_or_list(EditLine *el, int c)
+em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar) {
 					/* if I'm at the end */
 		if (el->el_line.cursor == el->el_line.buffer) {
 					/* and the beginning */
-			term_overwrite(el, STReof, 4);	/* then do an EOF */
+			term_overwrite(el, STReof, 4);	/* then do a EOF */
 			term__flush();
 			return (CC_EOF);
 		} else {
@@ -73,7 +72,10 @@
 			return (CC_ERROR);
 		}
 	} else {
-		c_delafter(el, el->el_state.argument);	/* delete after dot */
+		if (el->el_state.doingarg)
+			c_delafter(el, el->el_state.argument);
+		else
+			c_delafter1(el);
 		if (el->el_line.cursor > el->el_line.lastchar)
 			el->el_line.cursor = el->el_line.lastchar;
 				/* bounds check */
@@ -88,7 +90,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_delete_next_word(EditLine *el, int c)
+em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *p, *kp;
 
@@ -117,14 +119,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_yank(EditLine *el, int c)
+em_yank(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
-	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
-		if (!ch_enlargebufs(el, 1))
-			return (CC_ERROR);
-	}
+	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
+		return (CC_NORM);
 
 	if (el->el_line.lastchar +
 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
@@ -154,7 +154,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_kill_line(EditLine *el, int c)
+em_kill_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -176,7 +176,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_kill_region(EditLine *el, int c)
+em_kill_region(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -209,11 +209,11 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_copy_region(EditLine *el, int c)
+em_copy_region(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
-	if (el->el_chared.c_kill.mark)
+	if (!el->el_chared.c_kill.mark)
 		return (CC_ERROR);
 
 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
@@ -233,12 +233,12 @@
 }
 
 
-/* em_gosmacs_traspose():
+/* em_gosmacs_transpose():
  *	Exchange the two characters before the cursor
  *	Gosling emacs transpose chars [^T]
  */
 protected el_action_t
-em_gosmacs_traspose(EditLine *el, int c)
+em_gosmacs_transpose(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
@@ -258,7 +258,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_next_word(EditLine *el, int c)
+em_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	if (el->el_line.cursor == el->el_line.lastchar)
 		return (CC_ERROR);
@@ -269,7 +269,7 @@
 	    ce__isword);
 
 	if (el->el_map.type == MAP_VI)
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -283,7 +283,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_upper_case(EditLine *el, int c)
+em_upper_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -291,8 +291,8 @@
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++)
-		if (islower((unsigned char) *cp))
-			*cp = toupper((unsigned char) *cp);
+		if (islower((unsigned char)*cp))
+			*cp = toupper((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -307,7 +307,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_capitol_case(EditLine *el, int c)
+em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -315,16 +315,16 @@
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++) {
-		if (isalpha((unsigned char) *cp)) {
-			if (islower((unsigned char) *cp))
-				*cp = toupper((unsigned char) *cp);
+		if (isalpha((unsigned char)*cp)) {
+			if (islower((unsigned char)*cp))
+				*cp = toupper((unsigned char)*cp);
 			cp++;
 			break;
 		}
 	}
 	for (; cp < ep; cp++)
-		if (isupper((unsigned char) *cp))
-			*cp = tolower((unsigned char) *cp);
+		if (isupper((unsigned char)*cp))
+			*cp = tolower((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -339,7 +339,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_lower_case(EditLine *el, int c)
+em_lower_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -347,8 +347,8 @@
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++)
-		if (isupper((unsigned char) *cp))
-			*cp = tolower((unsigned char) *cp);
+		if (isupper((unsigned char)*cp))
+			*cp = tolower((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -363,7 +363,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_set_mark(EditLine *el, int c)
+em_set_mark(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_chared.c_kill.mark = el->el_line.cursor;
@@ -377,7 +377,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_exchange_mark(EditLine *el, int c)
+em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp;
 
@@ -394,7 +394,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_universal_argument(EditLine *el, int c)
+em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
 {				/* multiply current argument by 4 */
 
 	if (el->el_state.argument > 1000000)
@@ -411,7 +411,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_meta_next(EditLine *el, int c)
+em_meta_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_state.metanext = 1;
@@ -424,7 +424,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_toggle_overwrite(EditLine *el, int c)
+em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
@@ -438,7 +438,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_copy_prev_word(EditLine *el, int c)
+em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *oldc, *dp;
 
@@ -465,7 +465,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_inc_search_next(EditLine *el, int c)
+em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_search.patlen = 0;
@@ -478,9 +478,32 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-em_inc_search_prev(EditLine *el, int c)
+em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_search.patlen = 0;
 	return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
+}
+
+
+/* em_delete_prev_char():
+ *	Delete the character to the left of the cursor
+ *	[^?]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+{
+
+	if (el->el_line.cursor <= el->el_line.buffer)
+		return (CC_ERROR);
+
+	if (el->el_state.doingarg)
+		c_delbefore(el, el->el_state.argument);
+	else
+		c_delbefore1(el);
+	el->el_line.cursor -= el->el_state.argument;
+	if (el->el_line.cursor < el->el_line.buffer)
+		el->el_line.cursor = el->el_line.buffer;
+	return (CC_REFRESH);
 }
diff --exclude=CVS -ruN src.orig/lib/libedit/hist.c src/lib/libedit/hist.c
--- src.orig/lib/libedit/hist.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/hist.c	Thu Mar 31 17:54:33 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: hist.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)hist.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/hist.c,v 1.5 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/hist.c,v 1.4 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * hist.c: History access functions
  */
-#include "sys.h"
 #include <stdlib.h>
 #include "el.h"
 
@@ -130,18 +129,16 @@
 			el->el_history.eventno = h;
 			return (CC_ERROR);
 		}
-	(void) strncpy(el->el_line.buffer, hp,
+	(void) strlcpy(el->el_line.buffer, hp,
 			(size_t)(el->el_line.limit - el->el_line.buffer));
 	el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
 
-	if (el->el_line.lastchar > el->el_line.buffer) {
-		if (el->el_line.lastchar[-1] == '\n')
-			el->el_line.lastchar--;
-		if (el->el_line.lastchar[-1] == ' ')
-			el->el_line.lastchar--;
-		if (el->el_line.lastchar < el->el_line.buffer)
-			el->el_line.lastchar = el->el_line.buffer;
-	}
+	if (el->el_line.lastchar > el->el_line.buffer
+	    && el->el_line.lastchar[-1] == '\n')
+		el->el_line.lastchar--;
+	if (el->el_line.lastchar > el->el_line.buffer
+	    && el->el_line.lastchar[-1] == ' ')
+		el->el_line.lastchar--;
 #ifdef KSHVI
 	if (el->el_map.type == MAP_VI)
 		el->el_line.cursor = el->el_line.buffer;
@@ -153,21 +150,40 @@
 }
 
 
-/* hist_list()
- *	List history entries
+/* hist_command()
+ *	process a history command
  */
 protected int
-/*ARGSUSED*/
-hist_list(EditLine *el, int argc, char **argv)
+hist_command(EditLine *el, int argc, const char **argv)
 {
 	const char *str;
+	int num;
+	HistEvent ev;
 
 	if (el->el_history.ref == NULL)
 		return (-1);
-	for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
-		(void) fprintf(el->el_outfile, "%d %s",
-		    el->el_history.ev.num, str);
-	return (0);
+
+	if (argc == 1 || strcmp(argv[1], "list") == 0) {
+		 /* List history entries */
+
+		for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
+			(void) fprintf(el->el_outfile, "%d %s",
+			    el->el_history.ev.num, str);
+		return (0);
+	}
+
+	if (argc != 3)
+		return (-1);
+
+	num = (int)strtol(argv[2], NULL, 0);
+
+	if (strcmp(argv[1], "size") == 0)
+		return history(el->el_history.ref, &ev, H_SETSIZE, num);
+
+	if (strcmp(argv[1], "unique") == 0)
+		return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
+
+	return -1;
 }
 
 /* hist_enlargebuf()
diff --exclude=CVS -ruN src.orig/lib/libedit/hist.h src/lib/libedit/hist.h
--- src.orig/lib/libedit/hist.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/hist.h	Wed Mar 30 21:07:25 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)hist.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: hist.h,v 1.5 2000/09/04 22:06:30 lukem Exp $
- * $FreeBSD: src/lib/libedit/hist.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -66,7 +63,7 @@
 #define	HIST_FIRST(el)		HIST_FUN(el, H_FIRST, NULL)
 #define	HIST_LAST(el)		HIST_FUN(el, H_LAST, NULL)
 #define	HIST_PREV(el)		HIST_FUN(el, H_PREV, NULL)
-#define	HIST_EVENT(el, num)	HIST_FUN(el, H_EVENT, num)
+#define	HIST_SET(el, num)	HIST_FUN(el, H_SET, num)
 #define	HIST_LOAD(el, fname)	HIST_FUN(el, H_LOAD fname)
 #define	HIST_SAVE(el, fname)	HIST_FUN(el, H_SAVE fname)
 
@@ -74,7 +71,7 @@
 protected void		hist_end(EditLine *);
 protected el_action_t	hist_get(EditLine *);
 protected int		hist_set(EditLine *, hist_fun_t, ptr_t);
-protected int		hist_list(EditLine *, int, char **);
+protected int		hist_command(EditLine *, int, const char **);
 protected int		hist_enlargebuf(EditLine *, size_t, size_t);
 
 #endif /* _h_el_hist */
diff --exclude=CVS -ruN src.orig/lib/libedit/history.c src/lib/libedit/history.c
--- src.orig/lib/libedit/history.c	Mon Oct 14 04:42:38 2002
+++ src/lib/libedit/history.c	Thu Mar 31 17:54:39 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,25 +30,29 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: history.c,v 1.16 2000/09/04 22:06:30 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)history.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/history.c,v 1.7 2002/10/14 10:42:38 tjr Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * hist.c: History access functions
  */
-#include "sys.h"
-
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#ifdef HAVE_VIS_H
 #include <vis.h>
+#else
+#include "np/vis.h"
+#endif
 #include <sys/stat.h>
 
 static const char hist_cookie[] = "_HiStOrY_V2_\n";
@@ -75,6 +77,7 @@
 	history_efun_t h_enter;	/* Add an element		 */
 	history_efun_t h_add;	/* Append to an element		 */
 };
+
 #define	HNEXT(h, ev)		(*(h)->h_next)((h)->h_ref, ev)
 #define	HFIRST(h, ev)		(*(h)->h_first)((h)->h_ref, ev)
 #define	HPREV(h, ev)		(*(h)->h_prev)((h)->h_ref, ev)
@@ -85,13 +88,22 @@
 #define	HENTER(h, ev, str)	(*(h)->h_enter)((h)->h_ref, ev, str)
 #define	HADD(h, ev, str)	(*(h)->h_add)((h)->h_ref, ev, str)
 
+#define	h_strdup(a)	strdup(a)
 #define	h_malloc(a)	malloc(a)
 #define	h_realloc(a, b)	realloc((a), (b))
 #define	h_free(a)	free(a)
 
+typedef struct {
+    int		num;
+    char	*str;
+} HistEventPrivate;
+
+
 
 private int history_setsize(History *, HistEvent *, int);
 private int history_getsize(History *, HistEvent *);
+private int history_setunique(History *, HistEvent *, int);
+private int history_getunique(History *, HistEvent *);
 private int history_set_fun(History *, History *);
 private int history_load(History *, const char *);
 private int history_save(History *, const char *);
@@ -110,15 +122,17 @@
 	HistEvent ev;		/* What we return		 */
 	struct hentry_t *next;	/* Next entry			 */
 	struct hentry_t *prev;	/* Previous entry		 */
-}        hentry_t;
+} hentry_t;
 
 typedef struct history_t {
-	hentry_t list;		/* Fake list header element	 */
-	hentry_t *cursor;	/* Current element in the list	 */
-	int max;		/* Maximum number of events	 */
-	int cur;		/* Current number of events	 */
+	hentry_t list;		/* Fake list header element	*/
+	hentry_t *cursor;	/* Current element in the list	*/
+	int max;		/* Maximum number of events	*/
+	int cur;		/* Current number of events	*/
 	int eventid;		/* For generation of unique event id	 */
-}         history_t;
+	int flags;		/* History flags		*/
+#define H_UNIQUE	1	/* Store only unique elements	*/
+} history_t;
 
 private int history_def_first(ptr_t, HistEvent *);
 private int history_def_last(ptr_t, HistEvent *);
@@ -128,13 +142,19 @@
 private int history_def_set(ptr_t, HistEvent *, const int n);
 private int history_def_enter(ptr_t, HistEvent *, const char *);
 private int history_def_add(ptr_t, HistEvent *, const char *);
-private void history_def_init(ptr_t *, HistEvent *, int);
+private int history_def_init(ptr_t *, HistEvent *, int);
 private void history_def_clear(ptr_t, HistEvent *);
 private int history_def_insert(history_t *, HistEvent *, const char *);
 private void history_def_delete(history_t *, HistEvent *, hentry_t *);
 
-#define	history_def_setsize(p, num)(void) (((history_t *) p)->max = (num))
-#define	history_def_getsize(p)  (((history_t *) p)->cur)
+#define	history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
+#define	history_def_getsize(p)  (((history_t *)p)->cur)
+#define	history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
+#define	history_def_setunique(p, uni) \
+    if (uni) \
+	(((history_t *)p)->flags) |= H_UNIQUE; \
+    else \
+	(((history_t *)p)->flags) &= ~H_UNIQUE
 
 #define	he_strerror(code)	he_errlist[code]
 #define	he_seterrev(evp, code)	{\
@@ -227,20 +247,19 @@
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->next;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev, _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->next == &h->list) {
 		he_seterrev(ev, _HE_END_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->next;
+        *ev = h->cursor->ev;
+
 	return (0);
 }
 
@@ -253,21 +272,20 @@
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->prev;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev,
 		    (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->prev == &h->list) {
 		he_seterrev(ev, _HE_START_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->prev;
+        *ev = h->cursor->ev;
+
 	return (0);
 }
 
@@ -328,20 +346,20 @@
 	history_t *h = (history_t *) p;
 	size_t len;
 	char *s;
+	HistEventPrivate *evp = (void *)&h->cursor->ev;
 
 	if (h->cursor == &h->list)
 		return (history_def_enter(p, ev, str));
-	len = strlen(h->cursor->ev.str) + strlen(str) + 1;
+	len = strlen(evp->str) + strlen(str) + 1;
 	s = (char *) h_malloc(len);
-	if (!s) {
+	if (s == NULL) {
 		he_seterrev(ev, _HE_MALLOC_FAILED);
 		return (-1);
 	}
 	(void) strlcpy(s, h->cursor->ev.str, len);
 	(void) strlcat(s, str, len);
-	/* LINTED const cast */
-	h_free((ptr_t) h->cursor->ev.str);
-	h->cursor->ev.str = s;
+	h_free((ptr_t)evp->str);
+	evp->str = s;
 	*ev = h->cursor->ev;
 	return (0);
 }
@@ -352,15 +370,15 @@
  */
 /* ARGSUSED */
 private void
-history_def_delete(history_t *h, HistEvent *ev, hentry_t *hp)
+history_def_delete(history_t *h, 
+		   HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
 {
-
+	HistEventPrivate *evp = (void *)&hp->ev;
 	if (hp == &h->list)
 		abort();
 	hp->prev->next = hp->next;
 	hp->next->prev = hp->prev;
-	/* LINTED const cast */
-	h_free((ptr_t) hp->ev.str);
+	h_free((ptr_t) evp->str);
 	h_free(hp);
 	h->cur--;
 }
@@ -374,11 +392,11 @@
 {
 
 	h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
-	if (h->cursor)
-		h->cursor->ev.str = strdup(str);
-	if (!h->cursor || !h->cursor->ev.str) {
-		he_seterrev(ev, _HE_MALLOC_FAILED);
-		return (-1);
+	if (h->cursor == NULL)
+		goto oomem;
+	if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
+		h_free((ptr_t)h->cursor);
+		goto oomem;
 	}
 	h->cursor->ev.num = ++h->eventid;
 	h->cursor->next = h->list.next;
@@ -389,6 +407,9 @@
 
 	*ev = h->cursor->ev;
 	return (0);
+oomem:
+	he_seterrev(ev, _HE_MALLOC_FAILED);
+	return (-1);
 }
 
 
@@ -400,6 +421,10 @@
 {
 	history_t *h = (history_t *) p;
 
+	if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
+	    strcmp(h->list.next->ev.str, str) == 0)
+	    return (0); 
+
 	if (history_def_insert(h, ev, str) == -1)
 		return (-1);	/* error, keep error message */
 
@@ -407,10 +432,10 @@
          * Always keep at least one entry.
          * This way we don't have to check for the empty list.
          */
-	while (h->cur - 1 > h->max)
+	while (h->cur > h->max && h->cur > 0)
 		history_def_delete(h, ev, h->list.prev);
 
-	return (0);
+	return (1);
 }
 
 
@@ -418,10 +443,12 @@
  *	Default history initialization function
  */
 /* ARGSUSED */
-private void
-history_def_init(ptr_t *p, HistEvent *ev, int n)
+private int
+history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
 {
 	history_t *h = (history_t *) h_malloc(sizeof(history_t));
+	if (h == NULL)
+		return -1;
 
 	if (n <= 0)
 		n = 0;
@@ -432,7 +459,9 @@
 	h->list.ev.str = NULL;
 	h->list.ev.num = 0;
 	h->cursor = &h->list;
+	h->flags = 0;
 	*p = (ptr_t) h;
+	return 0;
 }
 
 
@@ -461,10 +490,15 @@
 public History *
 history_init(void)
 {
-	History *h = (History *) h_malloc(sizeof(History));
 	HistEvent ev;
+	History *h = (History *) h_malloc(sizeof(History));
+	if (h == NULL)
+		return NULL;
 
-	history_def_init(&h->h_ref, &ev, 0);
+	if (history_def_init(&h->h_ref, &ev, 0) == -1) {
+		h_free((ptr_t)h);
+		return NULL;
+	}
 	h->h_ent = -1;
 	h->h_next = history_def_next;
 	h->h_first = history_def_first;
@@ -520,18 +554,46 @@
 private int
 history_getsize(History *h, HistEvent *ev)
 {
-	int retval = 0;
-
 	if (h->h_next != history_def_next) {
 		he_seterrev(ev, _HE_NOT_ALLOWED);
 		return (-1);
 	}
-	retval = history_def_getsize(h->h_ref);
-	if (retval < -1) {
+	ev->num = history_def_getsize(h->h_ref);
+	if (ev->num < -1) {
 		he_seterrev(ev, _HE_SIZE_NEGATIVE);
 		return (-1);
 	}
-	ev->num = retval;
+	return (0);
+}
+
+
+/* history_setunique():
+ *	Set if adjacent equal events should not be entered in history.
+ */
+private int
+history_setunique(History *h, HistEvent *ev, int uni)
+{
+
+	if (h->h_next != history_def_next) {
+		he_seterrev(ev, _HE_NOT_ALLOWED);
+		return (-1);
+	}
+	history_def_setunique(h->h_ref, uni);
+	return (0);
+}
+
+
+/* history_getunique():
+ *	Get if adjacent equal events should not be entered in history.
+ */
+private int
+history_getunique(History *h, HistEvent *ev)
+{
+	if (h->h_next != history_def_next) {
+		he_seterrev(ev, _HE_NOT_ALLOWED);
+		return (-1);
+	}
+	ev->num = history_def_getunique(h->h_ref);
 	return (0);
 }
 
@@ -603,6 +665,8 @@
 		goto done;
 
 	ptr = h_malloc(max_size = 1024);
+	if (ptr == NULL)
+		goto done;
 	for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
 		char c = line[sz];
 
@@ -612,15 +676,24 @@
 			line[sz] = '\0';
 
 		if (max_size < sz) {
-			max_size = (sz + 1023) & ~1023;
-			ptr = h_realloc(ptr, max_size);
+			char *nptr;
+			max_size = (sz + 1024) & ~1023;
+			nptr = h_realloc(ptr, max_size);
+			if (nptr == NULL) {
+				i = -1;
+				goto oomem;
+			}
+			ptr = nptr;
 		}
 		(void) strunvis(ptr, line);
 		line[sz] = c;
-		HENTER(h, &ev, ptr);
+		if (HENTER(h, &ev, ptr) == -1) {
+			h_free((ptr_t)ptr);
+			return -1;
+		}
 	}
-	h_free(ptr);
-
+oomem:
+	h_free((ptr_t)ptr);
 done:
 	(void) fclose(fp);
 	return (i);
@@ -635,28 +708,40 @@
 {
 	FILE *fp;
 	HistEvent ev;
-	int i = 0, retval;
+	int i = -1, retval;
 	size_t len, max_size;
 	char *ptr;
 
 	if ((fp = fopen(fname, "w")) == NULL)
 		return (-1);
 
-	(void) fchmod(fileno(fp), S_IRUSR|S_IWUSR);
-	(void) fputs(hist_cookie, fp);
+	if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
+		goto done;
+	if (fputs(hist_cookie, fp) == EOF)
+		goto done;
 	ptr = h_malloc(max_size = 1024);
-	for (retval = HLAST(h, &ev);
+	if (ptr == NULL)
+		goto done;
+	for (i = 0, retval = HLAST(h, &ev);
 	    retval != -1;
 	    retval = HPREV(h, &ev), i++) {
 		len = strlen(ev.str) * 4;
 		if (len >= max_size) {
-			max_size = (len + 1023) & 1023;
-			ptr = h_realloc(ptr, max_size);
+			char *nptr;
+			max_size = (len + 1024) & ~1023;
+			nptr = h_realloc(ptr, max_size);
+			if (nptr == NULL) {
+				i = -1;
+				goto oomem;
+			}
+			ptr = nptr;
 		}
 		(void) strvis(ptr, ev.str, VIS_WHITE);
 		(void) fprintf(fp, "%s\n", ptr);
 	}
-	h_free(ptr);
+oomem:
+	h_free((ptr_t)ptr);
+done:
 	(void) fclose(fp);
 	return (i);
 }
@@ -753,6 +838,14 @@
 
 	case H_SETSIZE:
 		retval = history_setsize(h, ev, va_arg(va, int));
+		break;
+
+	case H_GETUNIQUE:
+		retval = history_getunique(h, ev);
+		break;
+
+	case H_SETUNIQUE:
+		retval = history_setunique(h, ev, va_arg(va, int));
 		break;
 
 	case H_ADD:
diff --exclude=CVS -ruN src.orig/lib/libedit/key.c src/lib/libedit/key.c
--- src.orig/lib/libedit/key.c	Mon Dec 30 14:18:03 2002
+++ src/lib/libedit/key.c	Thu Mar 31 17:54:47 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,22 +30,24 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: key.c,v 1.11 2001/01/23 15:55:30 jdolecek Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)key.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/key.c,v 1.9 2002/12/30 21:18:03 schweikh Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * key.c: This module contains the procedures for maintaining
  *	  the extended-key map.
  *
  *      An extended-key (key) is a sequence of keystrokes introduced
- *	with a sequence introducer and consisting of an arbitrary
+ *	with an sequence introducer and consisting of an arbitrary
  *	number of characters.  This module maintains a map (the el->el_key.map)
  *	to convert these extended-key sequences into input strs
  *	(XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
@@ -63,7 +63,6 @@
  *      1) It is not possible to have one key that is a
  *	   substr of another.
  */
-#include "sys.h"
 #include <string.h>
 #include <stdlib.h>
 
@@ -88,8 +87,9 @@
     key_value_t *, int);
 private key_node_t	*node__get(int);
 private void		 node__put(EditLine *, key_node_t *);
-private int		 node__delete(EditLine *, key_node_t **, char *);
-private int		 node_lookup(EditLine *, char *, key_node_t *, int);
+private int		 node__delete(EditLine *, key_node_t **, const char *);
+private int		 node_lookup(EditLine *, const char *, key_node_t *,
+    int);
 private int		 node_enum(EditLine *, key_node_t *, int);
 private int		 key__decode_char(char *, int, int);
 
@@ -216,7 +216,7 @@
  *
  */
 protected void
-key_clear(EditLine *el, el_action_t *map, char *in)
+key_clear(EditLine *el, el_action_t *map, const char *in)
 {
 
 	if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
@@ -233,7 +233,7 @@
  *      they exists.
  */
 protected int
-key_delete(EditLine *el, char *key)
+key_delete(EditLine *el, const char *key)
 {
 
 	if (key[0] == '\0') {
@@ -254,7 +254,7 @@
  *	Print entire el->el_key.map if null
  */
 protected void
-key_print(EditLine *el, char *key)
+key_print(EditLine *el, const char *key)
 {
 
 	/* do nothing if el->el_key.map is empty and null key specified */
@@ -353,7 +353,8 @@
 			break;
 		case XK_STR:
 		case XK_EXE:
-			ptr->val.str = strdup(val->str);
+			if ((ptr->val.str = el_strdup(val->str)) == NULL)
+				return -1;
 			break;
 		default:
 			EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
@@ -373,7 +374,7 @@
  *	Delete node that matches str
  */
 private int
-node__delete(EditLine *el, key_node_t **inptr, char *str)
+node__delete(EditLine *el, key_node_t **inptr, const char *str)
 {
 	key_node_t *ptr;
 	key_node_t *prev_ptr = NULL;
@@ -450,7 +451,7 @@
 
 
 /* node__get():
- *	Returns pointer to a key_node_t for ch.
+ *	Returns pointer to an key_node_t for ch.
  */
 private key_node_t *
 node__get(int ch)
@@ -475,7 +476,7 @@
  *	Print if last node
  */
 private int
-node_lookup(EditLine *el, char *str, key_node_t *ptr, int cnt)
+node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
 {
 	int ncnt;
 
@@ -565,7 +566,7 @@
  *	function specified by val
  */
 protected void
-key_kprint(EditLine *el, char *key, key_value_t *val, int ntype)
+key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
 {
 	el_bindings_t *fp;
 	char unparsbuf[EL_BUFSIZ];
@@ -608,8 +609,6 @@
 private int
 key__decode_char(char *buf, int cnt, int ch)
 {
-	ch = (unsigned char)ch;
-
 	if (ch == 0) {
 		buf[cnt++] = '^';
 		buf[cnt] = '@';
@@ -617,10 +616,10 @@
 	}
 	if (iscntrl(ch)) {
 		buf[cnt++] = '^';
-		if (ch == 0177)
+		if (ch == '\177')
 			buf[cnt] = '?';
 		else
-			buf[cnt] = toascii(ch) | 0100;
+			buf[cnt] = ch | 0100;
 	} else if (ch == '^') {
 		buf[cnt++] = '\\';
 		buf[cnt] = '^';
@@ -638,13 +637,15 @@
 	return (cnt);
 }
 
+
 /* key__decode_str():
  *	Make a printable version of the ey
  */
 protected char *
-key__decode_str(char *str, char *buf, char *sep)
+key__decode_str(const char *str, char *buf, const char *sep)
 {
-	char *b, *p;
+	char *b;
+	const char *p;
 
 	b = buf;
 	if (sep[0] != '\0')
@@ -663,7 +664,7 @@
 			if (*p == '\177')
 				*b++ = '?';
 			else
-				*b++ = toascii(*p) | 0100;
+				*b++ = *p | 0100;
 		} else if (*p == '^' || *p == '\\') {
 			*b++ = '\\';
 			*b++ = *p;
diff --exclude=CVS -ruN src.orig/lib/libedit/key.h src/lib/libedit/key.h
--- src.orig/lib/libedit/key.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/key.h	Wed Mar 30 21:09:07 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)key.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: key.h,v 1.4 2000/09/04 22:06:30 lukem Exp $
- * $FreeBSD: src/lib/libedit/key.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -62,6 +59,10 @@
 #define	XK_NOD	2
 #define	XK_EXE	3
 
+#undef key_end
+#undef key_clear
+#undef key_print
+
 protected int		 key_init(EditLine *);
 protected void		 key_end(EditLine *);
 protected key_value_t	*key_map_cmd(EditLine *, int);
@@ -69,10 +70,11 @@
 protected void		 key_reset(EditLine *);
 protected int		 key_get(EditLine *, char *, key_value_t *);
 protected void		 key_add(EditLine *, const char *, key_value_t *, int);
-protected void		 key_clear(EditLine *, el_action_t *, char *);
-protected int		 key_delete(EditLine *, char *);
-protected void		 key_print(EditLine *, char *);
-protected void	         key_kprint(EditLine *, char *, key_value_t *, int);
-protected char		*key__decode_str(char *, char *, char *);
+protected void		 key_clear(EditLine *, el_action_t *, const char *);
+protected int		 key_delete(EditLine *, const char *);
+protected void		 key_print(EditLine *, const char *);
+protected void	         key_kprint(EditLine *, const char *, key_value_t *,
+    int);
+protected char		*key__decode_str(const char *, char *, const char *);
 
 #endif /* _h_el_key */
diff --exclude=CVS -ruN src.orig/lib/libedit/makelist src/lib/libedit/makelist
--- src.orig/lib/libedit/makelist	Mon Aug  4 15:31:51 2003
+++ src/lib/libedit/makelist	Wed Mar 30 21:31:50 2005
@@ -1,6 +1,6 @@
 #!/bin/sh -
-#	$NetBSD: makelist,v 1.6 2000/09/04 23:45:18 lukem Exp $
-# $FreeBSD: src/lib/libedit/makelist,v 1.8 2003/08/04 21:31:51 ache Exp $
+#	$NetBSD: makelist,v 1.8 2003/03/10 21:21:10 christos Exp $
+# $FreeBSD$
 #
 # Copyright (c) 1992, 1993
 #	The Regents of the University of California.  All rights reserved.
@@ -40,8 +40,8 @@
 
 # makelist.sh: Automatically generate header files...
 
-AWK=/usr/bin/awk
-USAGE="usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
+AWK=awk
+USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
 
 if [ "x$1" = "x" ]
 then
diff --exclude=CVS -ruN src.orig/lib/libedit/map.c src/lib/libedit/map.c
--- src.orig/lib/libedit/map.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/map.c	Thu Mar 31 17:54:53 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,26 +30,27 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: map.c,v 1.13 2001/01/04 15:56:32 christos Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)map.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/map.c,v 1.8 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/map.c,v 1.7 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * map.c: Editor function definitions
  */
-#include "sys.h"
 #include <stdlib.h>
 #include "el.h"
 
 #define	N_KEYS 256
 
-private void	map_print_key(EditLine *, el_action_t *, char *);
+private void	map_print_key(EditLine *, el_action_t *, const char *);
 private void	map_print_some_keys(EditLine *, el_action_t *, int, int);
 private void	map_print_all_keys(EditLine *);
 private void	map_init_nls(EditLine *);
@@ -69,7 +68,7 @@
 	/*   5 */	ED_MOVE_TO_END,		/* ^E */
 	/*   6 */	ED_NEXT_CHAR,		/* ^F */
 	/*   7 */	ED_UNASSIGNED,		/* ^G */
-	/*   8 */	ED_DELETE_PREV_CHAR,	/* ^H */
+	/*   8 */	EM_DELETE_PREV_CHAR,	/* ^H */
 	/*   9 */	ED_UNASSIGNED,		/* ^I */
 	/*  10 */	ED_NEWLINE,		/* ^J */
 	/*  11 */	ED_KILL_LINE,		/* ^K */
@@ -188,7 +187,7 @@
 	/* 124 */	ED_INSERT,		/* | */
 	/* 125 */	ED_INSERT,		/* } */
 	/* 126 */	ED_INSERT,		/* ~ */
-	/* 127 */	ED_DELETE_PREV_CHAR,	/* ^? */
+	/* 127 */	EM_DELETE_PREV_CHAR,	/* ^? */
 	/* 128 */	ED_UNASSIGNED,		/* M-^@ */
 	/* 129 */	ED_UNASSIGNED,		/* M-^A */
 	/* 130 */	ED_UNASSIGNED,		/* M-^B */
@@ -377,7 +376,7 @@
 	/*   5 */	ED_MOVE_TO_END,		/* ^E */
 	/*   6 */	ED_NEXT_CHAR,		/* ^F */
 	/*   7 */	ED_UNASSIGNED,		/* ^G */
-	/*   8 */	ED_DELETE_PREV_CHAR,	/* ^H */   /* BackSpace key */
+	/*   8 */	VI_DELETE_PREV_CHAR,	/* ^H */   /* BackSpace key */
 	/*   9 */	ED_UNASSIGNED,		/* ^I */   /* Tab Key */
 	/*  10 */	ED_NEWLINE,		/* ^J */
 	/*  11 */	ED_KILL_LINE,		/* ^K */
@@ -497,135 +496,135 @@
 	/* 124 */	ED_INSERT,		/* | */
 	/* 125 */	ED_INSERT,		/* } */
 	/* 126 */	ED_INSERT,		/* ~ */
-	/* 127 */	ED_DELETE_PREV_CHAR,	/* ^? */
-	/* 128 */	ED_UNASSIGNED,		/* M-^@ */
-	/* 129 */	ED_UNASSIGNED,		/* M-^A */
-	/* 130 */	ED_UNASSIGNED,		/* M-^B */
-	/* 131 */	ED_UNASSIGNED,		/* M-^C */
-	/* 132 */	ED_UNASSIGNED,		/* M-^D */
-	/* 133 */	ED_UNASSIGNED,		/* M-^E */
-	/* 134 */	ED_UNASSIGNED,		/* M-^F */
-	/* 135 */	ED_UNASSIGNED,		/* M-^G */
-	/* 136 */	ED_UNASSIGNED,		/* M-^H */
-	/* 137 */	ED_UNASSIGNED,		/* M-^I */
-	/* 138 */	ED_UNASSIGNED,		/* M-^J */
-	/* 139 */	ED_UNASSIGNED,		/* M-^K */
-	/* 140 */	ED_UNASSIGNED,		/* M-^L */
-	/* 141 */	ED_UNASSIGNED,		/* M-^M */
-	/* 142 */	ED_UNASSIGNED,		/* M-^N */
-	/* 143 */	ED_UNASSIGNED,		/* M-^O */
-	/* 144 */	ED_UNASSIGNED,		/* M-^P */
-	/* 145 */	ED_UNASSIGNED,		/* M-^Q */
-	/* 146 */	ED_UNASSIGNED,		/* M-^R */
-	/* 147 */	ED_UNASSIGNED,		/* M-^S */
-	/* 148 */	ED_UNASSIGNED,		/* M-^T */
-	/* 149 */	ED_UNASSIGNED,		/* M-^U */
-	/* 150 */	ED_UNASSIGNED,		/* M-^V */
-	/* 151 */	ED_UNASSIGNED,		/* M-^W */
-	/* 152 */	ED_UNASSIGNED,		/* M-^X */
-	/* 153 */	ED_UNASSIGNED,		/* M-^Y */
-	/* 154 */	ED_UNASSIGNED,		/* M-^Z */
-	/* 155 */	ED_UNASSIGNED,		/* M-^[ */
-	/* 156 */	ED_UNASSIGNED,		/* M-^\ */
-	/* 157 */	ED_UNASSIGNED,		/* M-^] */
-	/* 158 */	ED_UNASSIGNED,		/* M-^^ */
-	/* 159 */	ED_UNASSIGNED,		/* M-^_ */
-	/* 160 */	ED_UNASSIGNED,		/* M-SPACE */
-	/* 161 */	ED_UNASSIGNED,		/* M-! */
-	/* 162 */	ED_UNASSIGNED,		/* M-" */
-	/* 163 */	ED_UNASSIGNED,		/* M-# */
-	/* 164 */	ED_UNASSIGNED,		/* M-$ */
-	/* 165 */	ED_UNASSIGNED,		/* M-% */
-	/* 166 */	ED_UNASSIGNED,		/* M-& */
-	/* 167 */	ED_UNASSIGNED,		/* M-' */
-	/* 168 */	ED_UNASSIGNED,		/* M-( */
-	/* 169 */	ED_UNASSIGNED,		/* M-) */
-	/* 170 */	ED_UNASSIGNED,		/* M-* */
-	/* 171 */	ED_UNASSIGNED,		/* M-+ */
-	/* 172 */	ED_UNASSIGNED,		/* M-, */
-	/* 173 */	ED_UNASSIGNED,		/* M-- */
-	/* 174 */	ED_UNASSIGNED,		/* M-. */
-	/* 175 */	ED_UNASSIGNED,		/* M-/ */
-	/* 176 */	ED_UNASSIGNED,		/* M-0 */
-	/* 177 */	ED_UNASSIGNED,		/* M-1 */
-	/* 178 */	ED_UNASSIGNED,		/* M-2 */
-	/* 179 */	ED_UNASSIGNED,		/* M-3 */
-	/* 180 */	ED_UNASSIGNED,		/* M-4 */
-	/* 181 */	ED_UNASSIGNED,		/* M-5 */
-	/* 182 */	ED_UNASSIGNED,		/* M-6 */
-	/* 183 */	ED_UNASSIGNED,		/* M-7 */
-	/* 184 */	ED_UNASSIGNED,		/* M-8 */
-	/* 185 */	ED_UNASSIGNED,		/* M-9 */
-	/* 186 */	ED_UNASSIGNED,		/* M-: */
-	/* 187 */	ED_UNASSIGNED,		/* M-; */
-	/* 188 */	ED_UNASSIGNED,		/* M-< */
-	/* 189 */	ED_UNASSIGNED,		/* M-= */
-	/* 190 */	ED_UNASSIGNED,		/* M-> */
-	/* 191 */	ED_UNASSIGNED,		/* M-? */
-	/* 192 */	ED_UNASSIGNED,		/* M-@ */
-	/* 193 */	ED_UNASSIGNED,		/* M-A */
-	/* 194 */	ED_UNASSIGNED,		/* M-B */
-	/* 195 */	ED_UNASSIGNED,		/* M-C */
-	/* 196 */	ED_UNASSIGNED,		/* M-D */
-	/* 197 */	ED_UNASSIGNED,		/* M-E */
-	/* 198 */	ED_UNASSIGNED,		/* M-F */
-	/* 199 */	ED_UNASSIGNED,		/* M-G */
-	/* 200 */	ED_UNASSIGNED,		/* M-H */
-	/* 201 */	ED_UNASSIGNED,		/* M-I */
-	/* 202 */	ED_UNASSIGNED,		/* M-J */
-	/* 203 */	ED_UNASSIGNED,		/* M-K */
-	/* 204 */	ED_UNASSIGNED,		/* M-L */
-	/* 205 */	ED_UNASSIGNED,		/* M-M */
-	/* 206 */	ED_UNASSIGNED,		/* M-N */
-	/* 207 */	ED_UNASSIGNED,		/* M-O */
-	/* 208 */	ED_UNASSIGNED,		/* M-P */
-	/* 209 */	ED_UNASSIGNED,		/* M-Q */
-	/* 210 */	ED_UNASSIGNED,		/* M-R */
-	/* 211 */	ED_UNASSIGNED,		/* M-S */
-	/* 212 */	ED_UNASSIGNED,		/* M-T */
-	/* 213 */	ED_UNASSIGNED,		/* M-U */
-	/* 214 */	ED_UNASSIGNED,		/* M-V */
-	/* 215 */	ED_UNASSIGNED,		/* M-W */
-	/* 216 */	ED_UNASSIGNED,		/* M-X */
-	/* 217 */	ED_UNASSIGNED,		/* M-Y */
-	/* 218 */	ED_UNASSIGNED,		/* M-Z */
-	/* 219 */	ED_UNASSIGNED,		/* M-[ */
-	/* 220 */	ED_UNASSIGNED,		/* M-\ */
-	/* 221 */	ED_UNASSIGNED,		/* M-] */
-	/* 222 */	ED_UNASSIGNED,		/* M-^ */
-	/* 223 */	ED_UNASSIGNED,		/* M-_ */
-	/* 224 */	ED_UNASSIGNED,		/* M-` */
-	/* 225 */	ED_UNASSIGNED,		/* M-a */
-	/* 226 */	ED_UNASSIGNED,		/* M-b */
-	/* 227 */	ED_UNASSIGNED,		/* M-c */
-	/* 228 */	ED_UNASSIGNED,		/* M-d */
-	/* 229 */	ED_UNASSIGNED,		/* M-e */
-	/* 230 */	ED_UNASSIGNED,		/* M-f */
-	/* 231 */	ED_UNASSIGNED,		/* M-g */
-	/* 232 */	ED_UNASSIGNED,		/* M-h */
-	/* 233 */	ED_UNASSIGNED,		/* M-i */
-	/* 234 */	ED_UNASSIGNED,		/* M-j */
-	/* 235 */	ED_UNASSIGNED,		/* M-k */
-	/* 236 */	ED_UNASSIGNED,		/* M-l */
-	/* 237 */	ED_UNASSIGNED,		/* M-m */
-	/* 238 */	ED_UNASSIGNED,		/* M-n */
-	/* 239 */	ED_UNASSIGNED,		/* M-o */
-	/* 240 */	ED_UNASSIGNED,		/* M-p */
-	/* 241 */	ED_UNASSIGNED,		/* M-q */
-	/* 242 */	ED_UNASSIGNED,		/* M-r */
-	/* 243 */	ED_UNASSIGNED,		/* M-s */
-	/* 244 */	ED_UNASSIGNED,		/* M-t */
-	/* 245 */	ED_UNASSIGNED,		/* M-u */
-	/* 246 */	ED_UNASSIGNED,		/* M-v */
-	/* 247 */	ED_UNASSIGNED,		/* M-w */
-	/* 248 */	ED_UNASSIGNED,		/* M-x */
-	/* 249 */	ED_UNASSIGNED,		/* M-y */
-	/* 250 */	ED_UNASSIGNED,		/* M-z */
-	/* 251 */	ED_UNASSIGNED,		/* M-{ */
-	/* 252 */	ED_UNASSIGNED,		/* M-| */
-	/* 253 */	ED_UNASSIGNED,		/* M-} */
-	/* 254 */	ED_UNASSIGNED,		/* M-~ */
-	/* 255 */	ED_UNASSIGNED		/* M-^? */
+	/* 127 */	VI_DELETE_PREV_CHAR,	/* ^? */
+	/* 128 */	ED_INSERT,		/* M-^@ */
+	/* 129 */	ED_INSERT,		/* M-^A */
+	/* 130 */	ED_INSERT,		/* M-^B */
+	/* 131 */	ED_INSERT,		/* M-^C */
+	/* 132 */	ED_INSERT,		/* M-^D */
+	/* 133 */	ED_INSERT,		/* M-^E */
+	/* 134 */	ED_INSERT,		/* M-^F */
+	/* 135 */	ED_INSERT,		/* M-^G */
+	/* 136 */	ED_INSERT,		/* M-^H */
+	/* 137 */	ED_INSERT,		/* M-^I */
+	/* 138 */	ED_INSERT,		/* M-^J */
+	/* 139 */	ED_INSERT,		/* M-^K */
+	/* 140 */	ED_INSERT,		/* M-^L */
+	/* 141 */	ED_INSERT,		/* M-^M */
+	/* 142 */	ED_INSERT,		/* M-^N */
+	/* 143 */	ED_INSERT,		/* M-^O */
+	/* 144 */	ED_INSERT,		/* M-^P */
+	/* 145 */	ED_INSERT,		/* M-^Q */
+	/* 146 */	ED_INSERT,		/* M-^R */
+	/* 147 */	ED_INSERT,		/* M-^S */
+	/* 148 */	ED_INSERT,		/* M-^T */
+	/* 149 */	ED_INSERT,		/* M-^U */
+	/* 150 */	ED_INSERT,		/* M-^V */
+	/* 151 */	ED_INSERT,		/* M-^W */
+	/* 152 */	ED_INSERT,		/* M-^X */
+	/* 153 */	ED_INSERT,		/* M-^Y */
+	/* 154 */	ED_INSERT,		/* M-^Z */
+	/* 155 */	ED_INSERT,		/* M-^[ */
+	/* 156 */	ED_INSERT,		/* M-^\ */
+	/* 157 */	ED_INSERT,		/* M-^] */
+	/* 158 */	ED_INSERT,		/* M-^^ */
+	/* 159 */	ED_INSERT,		/* M-^_ */
+	/* 160 */	ED_INSERT,		/* M-SPACE */
+	/* 161 */	ED_INSERT,		/* M-! */
+	/* 162 */	ED_INSERT,		/* M-" */
+	/* 163 */	ED_INSERT,		/* M-# */
+	/* 164 */	ED_INSERT,		/* M-$ */
+	/* 165 */	ED_INSERT,		/* M-% */
+	/* 166 */	ED_INSERT,		/* M-& */
+	/* 167 */	ED_INSERT,		/* M-' */
+	/* 168 */	ED_INSERT,		/* M-( */
+	/* 169 */	ED_INSERT,		/* M-) */
+	/* 170 */	ED_INSERT,		/* M-* */
+	/* 171 */	ED_INSERT,		/* M-+ */
+	/* 172 */	ED_INSERT,		/* M-, */
+	/* 173 */	ED_INSERT,		/* M-- */
+	/* 174 */	ED_INSERT,		/* M-. */
+	/* 175 */	ED_INSERT,		/* M-/ */
+	/* 176 */	ED_INSERT,		/* M-0 */
+	/* 177 */	ED_INSERT,		/* M-1 */
+	/* 178 */	ED_INSERT,		/* M-2 */
+	/* 179 */	ED_INSERT,		/* M-3 */
+	/* 180 */	ED_INSERT,		/* M-4 */
+	/* 181 */	ED_INSERT,		/* M-5 */
+	/* 182 */	ED_INSERT,		/* M-6 */
+	/* 183 */	ED_INSERT,		/* M-7 */
+	/* 184 */	ED_INSERT,		/* M-8 */
+	/* 185 */	ED_INSERT,		/* M-9 */
+	/* 186 */	ED_INSERT,		/* M-: */
+	/* 187 */	ED_INSERT,		/* M-; */
+	/* 188 */	ED_INSERT,		/* M-< */
+	/* 189 */	ED_INSERT,		/* M-= */
+	/* 190 */	ED_INSERT,		/* M-> */
+	/* 191 */	ED_INSERT,		/* M-? */
+	/* 192 */	ED_INSERT,		/* M-@ */
+	/* 193 */	ED_INSERT,		/* M-A */
+	/* 194 */	ED_INSERT,		/* M-B */
+	/* 195 */	ED_INSERT,		/* M-C */
+	/* 196 */	ED_INSERT,		/* M-D */
+	/* 197 */	ED_INSERT,		/* M-E */
+	/* 198 */	ED_INSERT,		/* M-F */
+	/* 199 */	ED_INSERT,		/* M-G */
+	/* 200 */	ED_INSERT,		/* M-H */
+	/* 201 */	ED_INSERT,		/* M-I */
+	/* 202 */	ED_INSERT,		/* M-J */
+	/* 203 */	ED_INSERT,		/* M-K */
+	/* 204 */	ED_INSERT,		/* M-L */
+	/* 205 */	ED_INSERT,		/* M-M */
+	/* 206 */	ED_INSERT,		/* M-N */
+	/* 207 */	ED_INSERT,		/* M-O */
+	/* 208 */	ED_INSERT,		/* M-P */
+	/* 209 */	ED_INSERT,		/* M-Q */
+	/* 210 */	ED_INSERT,		/* M-R */
+	/* 211 */	ED_INSERT,		/* M-S */
+	/* 212 */	ED_INSERT,		/* M-T */
+	/* 213 */	ED_INSERT,		/* M-U */
+	/* 214 */	ED_INSERT,		/* M-V */
+	/* 215 */	ED_INSERT,		/* M-W */
+	/* 216 */	ED_INSERT,		/* M-X */
+	/* 217 */	ED_INSERT,		/* M-Y */
+	/* 218 */	ED_INSERT,		/* M-Z */
+	/* 219 */	ED_INSERT,		/* M-[ */
+	/* 220 */	ED_INSERT,		/* M-\ */
+	/* 221 */	ED_INSERT,		/* M-] */
+	/* 222 */	ED_INSERT,		/* M-^ */
+	/* 223 */	ED_INSERT,		/* M-_ */
+	/* 224 */	ED_INSERT,		/* M-` */
+	/* 225 */	ED_INSERT,		/* M-a */
+	/* 226 */	ED_INSERT,		/* M-b */
+	/* 227 */	ED_INSERT,		/* M-c */
+	/* 228 */	ED_INSERT,		/* M-d */
+	/* 229 */	ED_INSERT,		/* M-e */
+	/* 230 */	ED_INSERT,		/* M-f */
+	/* 231 */	ED_INSERT,		/* M-g */
+	/* 232 */	ED_INSERT,		/* M-h */
+	/* 233 */	ED_INSERT,		/* M-i */
+	/* 234 */	ED_INSERT,		/* M-j */
+	/* 235 */	ED_INSERT,		/* M-k */
+	/* 236 */	ED_INSERT,		/* M-l */
+	/* 237 */	ED_INSERT,		/* M-m */
+	/* 238 */	ED_INSERT,		/* M-n */
+	/* 239 */	ED_INSERT,		/* M-o */
+	/* 240 */	ED_INSERT,		/* M-p */
+	/* 241 */	ED_INSERT,		/* M-q */
+	/* 242 */	ED_INSERT,		/* M-r */
+	/* 243 */	ED_INSERT,		/* M-s */
+	/* 244 */	ED_INSERT,		/* M-t */
+	/* 245 */	ED_INSERT,		/* M-u */
+	/* 246 */	ED_INSERT,		/* M-v */
+	/* 247 */	ED_INSERT,		/* M-w */
+	/* 248 */	ED_INSERT,		/* M-x */
+	/* 249 */	ED_INSERT,		/* M-y */
+	/* 250 */	ED_INSERT,		/* M-z */
+	/* 251 */	ED_INSERT,		/* M-{ */
+	/* 252 */	ED_INSERT,		/* M-| */
+	/* 253 */	ED_INSERT,		/* M-} */
+	/* 254 */	ED_INSERT,		/* M-~ */
+	/* 255 */	ED_INSERT		/* M-^? */
 };
 
 private const el_action_t el_map_vi_command[] = {
@@ -637,7 +636,7 @@
 	/*   5 */	ED_MOVE_TO_END,		/* ^E */
 	/*   6 */	ED_UNASSIGNED,		/* ^F */
 	/*   7 */	ED_UNASSIGNED,		/* ^G */
-	/*   8 */	ED_PREV_CHAR,		/* ^H */
+	/*   8 */	ED_DELETE_PREV_CHAR,	/* ^H */
 	/*   9 */	ED_UNASSIGNED,		/* ^I */
 	/*  10 */	ED_NEWLINE,		/* ^J */
 	/*  11 */	ED_KILL_LINE,		/* ^K */
@@ -664,9 +663,9 @@
 	/*  32 */	ED_NEXT_CHAR,		/* SPACE */
 	/*  33 */	ED_UNASSIGNED,		/* ! */
 	/*  34 */	ED_UNASSIGNED,		/* " */
-	/*  35 */	ED_UNASSIGNED,		/* # */
+	/*  35 */	VI_COMMENT_OUT,		/* # */
 	/*  36 */	ED_MOVE_TO_END,		/* $ */
-	/*  37 */	ED_UNASSIGNED,		/* % */
+	/*  37 */	VI_MATCH,		/* % */
 	/*  38 */	ED_UNASSIGNED,		/* & */
 	/*  39 */	ED_UNASSIGNED,		/* ' */
 	/*  40 */	ED_UNASSIGNED,		/* ( */
@@ -675,7 +674,7 @@
 	/*  43 */	ED_NEXT_HISTORY,	/* + */
 	/*  44 */	VI_REPEAT_PREV_CHAR,	/* , */
 	/*  45 */	ED_PREV_HISTORY,	/* - */
-	/*  46 */	ED_UNASSIGNED,		/* . */
+	/*  46 */	VI_REDO,		/* . */
 	/*  47 */	VI_SEARCH_PREV,		/* / */
 	/*  48 */	VI_ZERO,		/* 0 */
 	/*  49 */	ED_ARGUMENT_DIGIT,	/* 1 */
@@ -693,14 +692,14 @@
 	/*  61 */	ED_UNASSIGNED,		/* = */
 	/*  62 */	ED_UNASSIGNED,		/* > */
 	/*  63 */	VI_SEARCH_NEXT,		/* ? */
-	/*  64 */	ED_UNASSIGNED,		/* @ */
+	/*  64 */	VI_ALIAS,		/* @ */
 	/*  65 */	VI_ADD_AT_EOL,		/* A */
-	/*  66 */	VI_PREV_SPACE_WORD,	/* B */
+	/*  66 */	VI_PREV_BIG_WORD,	/* B */
 	/*  67 */	VI_CHANGE_TO_EOL,	/* C */
 	/*  68 */	ED_KILL_LINE,		/* D */
-	/*  69 */	VI_TO_END_WORD,		/* E */
+	/*  69 */	VI_END_BIG_WORD,	/* E */
 	/*  70 */	VI_PREV_CHAR,		/* F */
-	/*  71 */	ED_UNASSIGNED,		/* G */
+	/*  71 */	VI_TO_HISTORY_LINE,	/* G */
 	/*  72 */	ED_UNASSIGNED,		/* H */
 	/*  73 */	VI_INSERT_AT_BOL,	/* I */
 	/*  74 */	ED_SEARCH_NEXT_HISTORY,	/* J */
@@ -716,15 +715,15 @@
 	/*  84 */	VI_TO_PREV_CHAR,	/* T */
 	/*  85 */	VI_UNDO_LINE,		/* U */
 	/*  86 */	ED_UNASSIGNED,		/* V */
-	/*  87 */	VI_NEXT_SPACE_WORD,	/* W */
+	/*  87 */	VI_NEXT_BIG_WORD,	/* W */
 	/*  88 */	ED_DELETE_PREV_CHAR,	/* X */
-	/*  89 */	ED_UNASSIGNED,		/* Y */
+	/*  89 */	VI_YANK_END,		/* Y */
 	/*  90 */	ED_UNASSIGNED,		/* Z */
 	/*  91 */	ED_SEQUENCE_LEAD_IN,	/* [ */
 	/*  92 */	ED_UNASSIGNED,		/* \ */
 	/*  93 */	ED_UNASSIGNED,		/* ] */
 	/*  94 */	ED_MOVE_TO_BEG,		/* ^ */
-	/*  95 */	ED_UNASSIGNED,		/* _ */
+	/*  95 */	VI_HISTORY_WORD,	/* _ */
 	/*  96 */	ED_UNASSIGNED,		/* ` */
 	/*  97 */	VI_ADD,			/* a */
 	/*  98 */	VI_PREV_WORD,		/* b */
@@ -747,13 +746,13 @@
 	/* 115 */	VI_SUBSTITUTE_CHAR,	/* s */
 	/* 116 */	VI_TO_NEXT_CHAR,	/* t */
 	/* 117 */	VI_UNDO,		/* u */
-	/* 118 */	ED_UNASSIGNED,		/* v */
+	/* 118 */	VI_HISTEDIT,		/* v */
 	/* 119 */	VI_NEXT_WORD,		/* w */
 	/* 120 */	ED_DELETE_NEXT_CHAR,	/* x */
-	/* 121 */	ED_UNASSIGNED,		/* y */
+	/* 121 */	VI_YANK,		/* y */
 	/* 122 */	ED_UNASSIGNED,		/* z */
 	/* 123 */	ED_UNASSIGNED,		/* { */
-	/* 124 */	ED_UNASSIGNED,		/* | */
+	/* 124 */	VI_TO_COLUMN,		/* | */
 	/* 125 */	ED_UNASSIGNED,		/* } */
 	/* 126 */	VI_CHANGE_CASE,		/* ~ */
 	/* 127 */	ED_DELETE_PREV_CHAR,	/* ^? */
@@ -1124,7 +1123,7 @@
  *	Print the function description for 1 key
  */
 private void
-map_print_key(EditLine *el, el_action_t *map, char *in)
+map_print_key(EditLine *el, el_action_t *map, const char *in)
 {
 	char outbuf[EL_BUFSIZ];
 	el_bindings_t *bp;
@@ -1237,14 +1236,14 @@
  *	Add/remove/change bindings
  */
 protected int
-map_bind(EditLine *el, int argc, char **argv)
+map_bind(EditLine *el, int argc, const char **argv)
 {
 	el_action_t *map;
 	int ntype, rem;
-	char *p;
+	const char *p;
 	char inbuf[EL_BUFSIZ];
 	char outbuf[EL_BUFSIZ];
-	char *in = NULL;
+	const char *in = NULL;
 	char *out = NULL;
 	el_bindings_t *bp;
 	int cmd;
@@ -1395,10 +1394,10 @@
 	if (name == NULL || help == NULL || func == NULL)
 		return (-1);
 
-	if ((p = el_reallocf(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
+	if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
 		return (-1);
 	el->el_map.func = (el_func_t *) p;
-	if ((p = el_reallocf(el->el_map.help, nf * sizeof(el_bindings_t)))
+	if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
 	    == NULL)
 		return (-1);
 	el->el_map.help = (el_bindings_t *) p;
diff --exclude=CVS -ruN src.orig/lib/libedit/map.h src/lib/libedit/map.h
--- src.orig/lib/libedit/map.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/map.h	Wed Mar 30 21:25:23 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)map.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: map.h,v 1.5 2000/09/04 22:06:31 lukem Exp $
- * $FreeBSD: src/lib/libedit/map.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -67,7 +64,7 @@
 #define	MAP_EMACS	0
 #define	MAP_VI		1
 
-protected int	map_bind(EditLine *, int, char **);
+protected int	map_bind(EditLine *, int, const char **);
 protected int	map_init(EditLine *);
 protected void	map_end(EditLine *);
 protected void	map_init_vi(EditLine *);
diff --exclude=CVS -ruN src.orig/lib/libedit/parse.c src/lib/libedit/parse.c
--- src.orig/lib/libedit/parse.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/parse.c	Thu Mar 31 17:55:08 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,15 +30,17 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: parse.c,v 1.13 2000/09/04 22:06:31 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)parse.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/parse.c,v 1.9 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/parse.c,v 1.8 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * parse.c: parse an editline extended command
@@ -55,19 +55,17 @@
  *	settc
  *	setty
  */
-#include "sys.h"
 #include "el.h"
-#include "tokenizer.h"
 #include <stdlib.h>
 
 private const struct {
-	char *name;
-	int (*func)(EditLine *, int, char **);
+	const char *name;
+	int (*func)(EditLine *, int, const char **);
 } cmds[] = {
 	{ "bind",	map_bind	},
 	{ "echotc",	term_echotc	},
 	{ "edit",	el_editmode	},
-	{ "history",	hist_list	},
+	{ "history",	hist_command	},
 	{ "telltc",	term_telltc	},
 	{ "settc",	term_settc	},
 	{ "setty",	tty_stty	},
@@ -81,12 +79,12 @@
 protected int
 parse_line(EditLine *el, const char *line)
 {
-	char **argv;
+	const char **argv;
 	int argc;
 	Tokenizer *tok;
 
 	tok = tok_init(NULL);
-	tok_line(tok, line, &argc, &argv);
+	tok_str(tok, line, &argc, &argv);
 	argc = el_parse(el, argc, argv);
 	tok_end(tok);
 	return (argc);
@@ -97,9 +95,9 @@
  *	Command dispatcher
  */
 public int
-el_parse(EditLine *el, int argc, char *argv[])
+el_parse(EditLine *el, int argc, const char *argv[])
 {
-	char *ptr;
+	const char *ptr;
 	int i;
 
 	if (argc < 1)
@@ -204,14 +202,15 @@
 			c = *p;
 			break;
 		}
-	} else if (*p == '^' && isascii(p[1]) && (p[1] == '?' || isalpha(p[1])))  {
+	} else if (*p == '^') {
 		p++;
 		c = (*p == '?') ? '\177' : (*p & 0237);
 	} else
 		c = *p;
 	*ptr = ++p;
-	return ((unsigned char)c);
+	return (c);
 }
+
 /* parse__string():
  *	Parse the escapes from in and put the raw string out
  */
@@ -233,6 +232,14 @@
 				return (NULL);
 			*out++ = n;
 			break;
+
+		case 'M':
+			if (in[1] == '-' && in[2] != '\0') {
+				*out++ = '\033';
+				in += 2;
+				break;
+			}
+			/*FALLTHROUGH*/
 
 		default:
 			*out++ = *in++;
diff --exclude=CVS -ruN src.orig/lib/libedit/parse.h src/lib/libedit/parse.h
--- src.orig/lib/libedit/parse.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/parse.h	Wed Mar 30 21:10:31 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)parse.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: parse.h,v 1.3 1999/07/02 15:21:26 simonb Exp $
- * $FreeBSD: src/lib/libedit/parse.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
diff --exclude=CVS -ruN src.orig/lib/libedit/prompt.c src/lib/libedit/prompt.c
--- src.orig/lib/libedit/prompt.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/prompt.c	Thu Mar 31 17:55:14 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: prompt.c,v 1.7 2000/09/04 22:06:31 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)prompt.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/prompt.c,v 1.5 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/prompt.c,v 1.4 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * prompt.c: Prompt printing functions
  */
-#include "sys.h"
 #include <stdio.h>
 #include "el.h"
 
@@ -57,7 +56,7 @@
  */
 private char *
 /*ARGSUSED*/
-prompt_default(EditLine *el)
+prompt_default(EditLine *el __attribute__((__unused__)))
 {
 	static char a[3] = {'?', ' ', '\0'};
 
@@ -70,7 +69,7 @@
  */
 private char *
 /*ARGSUSED*/
-prompt_default_r(EditLine *el)
+prompt_default_r(EditLine *el __attribute__((__unused__)))
 {
 	static char a[1] = {'\0'};
 
@@ -125,7 +124,7 @@
  */
 protected void
 /*ARGSUSED*/
-prompt_end(EditLine *el)
+prompt_end(EditLine *el __attribute__((__unused__)))
 {
 }
 
diff --exclude=CVS -ruN src.orig/lib/libedit/prompt.h src/lib/libedit/prompt.h
--- src.orig/lib/libedit/prompt.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/prompt.h	Wed Mar 30 21:11:24 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)prompt.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: prompt.h,v 1.4 1999/11/12 01:05:07 lukem Exp $
- * $FreeBSD: src/lib/libedit/prompt.h,v 1.2 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
diff --exclude=CVS -ruN src.orig/lib/libedit/read.c src/lib/libedit/read.c
--- src.orig/lib/libedit/read.c	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/read.c	Thu Mar 31 17:55:23 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,21 +30,22 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: read.c,v 1.18 2000/11/11 22:18:58 christos Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)read.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/read.c,v 1.11 2001/10/01 08:41:25 obrien Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * read.c: Clean this junk up! This is horrible code.
  *	   Terminal read functions
  */
-#include "sys.h"
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -57,8 +56,48 @@
 
 private int	read__fixio(int, int);
 private int	read_preread(EditLine *);
-private int	read_getcmd(EditLine *, el_action_t *, char *);
 private int	read_char(EditLine *, char *);
+private int	read_getcmd(EditLine *, el_action_t *, char *);
+
+/* read_init():
+ *	Initialize the read stuff
+ */
+protected int
+read_init(EditLine *el)
+{
+	/* builtin read_char */
+	el->el_read.read_char = read_char;
+	return 0;
+}
+
+
+/* el_read_setfn():
+ *	Set the read char function to the one provided.
+ *	If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
+ */
+protected int
+el_read_setfn(EditLine *el, el_rfunc_t rc)
+{
+	el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
+	return 0;
+}
+
+
+/* el_read_getfn():
+ *	return the current read char function, or EL_BUILTIN_GETCFN
+ *	if it is the default one
+ */
+protected el_rfunc_t
+el_read_getfn(EditLine *el)
+{
+       return (el->el_read.read_char == read_char) ?
+	    EL_BUILTIN_GETCFN : el->el_read.read_char;
+}
+
+
+#ifndef MIN
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#endif
 
 #ifdef DEBUG_EDIT
 private void
@@ -84,7 +123,7 @@
  */
 /* ARGSUSED */
 private int
-read__fixio(int fd, int e)
+read__fixio(int fd __attribute__((__unused__)), int e)
 {
 
 	switch (e) {
@@ -149,10 +188,6 @@
 {
 	int chrs = 0;
 
-	if (el->el_chared.c_macro.nline) {
-		el_free((ptr_t) el->el_chared.c_macro.nline);
-		el->el_chared.c_macro.nline = NULL;
-	}
 	if (el->el_tty.t_mode == ED_IO)
 		return (0);
 
@@ -165,8 +200,7 @@
 		    (size_t) MIN(chrs, EL_BUFSIZ - 1));
 		if (chrs > 0) {
 			buf[chrs] = '\0';
-			el->el_chared.c_macro.nline = strdup(buf);
-			el_push(el, el->el_chared.c_macro.nline);
+			el_push(el, buf);
 		}
 	}
 #endif /* FIONREAD */
@@ -179,18 +213,18 @@
  *	Push a macro
  */
 public void
-el_push(EditLine *el, const char *str)
+el_push(EditLine *el, char *str)
 {
 	c_macro_t *ma = &el->el_chared.c_macro;
 
 	if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
 		ma->level++;
-		/* LINTED const cast */
-		ma->macro[ma->level] = (char *) str;
-	} else {
-		term_beep(el);
-		term__flush();
+		if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
+			return;
+		ma->level--;
 	}
+	term_beep(el);
+	term__flush();
 }
 
 
@@ -200,10 +234,10 @@
 private int
 read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
 {
-	el_action_t cmd = ED_UNASSIGNED;
+	el_action_t cmd;
 	int num;
 
-	while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
+	do {
 		if ((num = el_getc(el, ch)) != 1)	/* if EOF or error */
 			return (num);
 
@@ -242,7 +276,7 @@
 		}
 		if (el->el_map.alt == NULL)
 			el->el_map.current = el->el_map.key;
-	}
+	} while (cmd == ED_SEQUENCE_LEAD_IN);
 	*cmdnum = cmd;
 	return (OKCMD);
 }
@@ -287,14 +321,16 @@
 		if (ma->level < 0)
 			break;
 
-		if (*ma->macro[ma->level] == 0) {
-			ma->level--;
+		if (ma->macro[ma->level][ma->offset] == '\0') {
+			el_free(ma->macro[ma->level--]);
+			ma->offset = 0;
 			continue;
 		}
-		*cp = *ma->macro[ma->level]++ & 0377;
-		if (*ma->macro[ma->level] == 0) {	/* Needed for QuoteMode
-							 * On */
-			ma->level--;
+		*cp = ma->macro[ma->level][ma->offset++] & 0377;
+		if (ma->macro[ma->level][ma->offset] == '\0') {
+			/* Needed for QuoteMode On */
+			el_free(ma->macro[ma->level--]);
+			ma->offset = 0;
 		}
 		return (1);
 	}
@@ -308,13 +344,42 @@
 #ifdef DEBUG_READ
 	(void) fprintf(el->el_errfile, "Reading a character\n");
 #endif /* DEBUG_READ */
-	num_read = read_char(el, cp);
+	num_read = (*el->el_read.read_char)(el, cp);
 #ifdef DEBUG_READ
 	(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
 #endif /* DEBUG_READ */
 	return (num_read);
 }
 
+protected void
+read_prepare(EditLine *el)
+{
+	if (el->el_flags & HANDLE_SIGNALS)
+		sig_set(el);
+	if (el->el_flags & NO_TTY)
+		return;
+	if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
+		tty_rawmode(el);
+
+	/* This is relatively cheap, and things go terribly wrong if
+	   we have the wrong size. */
+	el_resize(el);
+	re_clear_display(el);	/* reset the display stuff */
+	ch_reset(el);
+	re_refresh(el);		/* print the prompt */
+
+	if (el->el_flags & UNBUFFERED)
+		term__flush();
+}
+
+protected void
+read_finish(EditLine *el)
+{
+	if ((el->el_flags & UNBUFFERED) == 0)
+		(void) tty_cookedmode(el);
+	if (el->el_flags & HANDLE_SIGNALS)
+		sig_clr(el);
+}
 
 public const char *
 el_gets(EditLine *el, int *nread)
@@ -323,18 +388,16 @@
 	el_action_t cmdnum = 0;
 	int num;		/* how many chars we have read at NL */
 	char ch;
+	int crlf = 0;
 #ifdef FIONREAD
 	c_macro_t *ma = &el->el_chared.c_macro;
 #endif /* FIONREAD */
 
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_set(el);
-
 	if (el->el_flags & NO_TTY) {
 		char *cp = el->el_line.buffer;
 		size_t idx;
 
-		while (read_char(el, cp) == 1) {
+		while ((*el->el_read.read_char)(el, cp) == 1) {
 			/* make sure there is space for next character */
 			if (cp + 1 >= el->el_line.limit) {
 				idx = (cp - el->el_line.buffer);
@@ -343,6 +406,8 @@
 				cp = &el->el_line.buffer[idx];
 			}
 			cp++;
+			if (el->el_flags & UNBUFFERED)
+				break;
 			if (cp[-1] == '\r' || cp[-1] == '\n')
 				break;
 		}
@@ -353,8 +418,7 @@
 			*nread = el->el_line.cursor - el->el_line.buffer;
 		return (el->el_line.buffer);
 	}
-	re_clear_display(el);	/* reset the display stuff */
-	ch_reset(el);
+
 
 #ifdef FIONREAD
 	if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
@@ -371,15 +435,20 @@
 	}
 #endif /* FIONREAD */
 
-	re_refresh(el);		/* print the prompt */
+	if ((el->el_flags & UNBUFFERED) == 0)
+		read_prepare(el);
 
 	if (el->el_flags & EDIT_DISABLED) {
-		char *cp = el->el_line.buffer;
+		char *cp;
 		size_t idx;
+		if ((el->el_flags & UNBUFFERED) == 0)
+			cp = el->el_line.buffer;
+		else
+			cp = el->el_line.lastchar;
 
 		term__flush();
 
-		while (read_char(el, cp) == 1) {
+		while ((*el->el_read.read_char)(el, cp) == 1) {
 			/* make sure there is space next character */
 			if (cp + 1 >= el->el_line.limit) {
 				idx = (cp - el->el_line.buffer);
@@ -387,8 +456,13 @@
 					break;
 				cp = &el->el_line.buffer[idx];
 			}
+			if (*cp == 4)	/* ought to be stty eof */
+				break;
 			cp++;
-			if (cp[-1] == '\r' || cp[-1] == '\n')
+			crlf = cp[-1] == '\r' || cp[-1] == '\n';
+			if (el->el_flags & UNBUFFERED)
+				break;
+			if (crlf)
 				break;
 		}
 
@@ -398,6 +472,7 @@
 			*nread = el->el_line.cursor - el->el_line.buffer;
 		return (el->el_line.buffer);
 	}
+
 	for (num = OKCMD; num == OKCMD;) {	/* while still editing this
 						 * line */
 #ifdef DEBUG_EDIT
@@ -411,7 +486,7 @@
 #endif /* DEBUG_READ */
 			break;
 		}
-		if ((int) cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
+		if ((int)cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
 #ifdef DEBUG_EDIT
 			(void) fprintf(el->el_errfile,
 			    "ERROR: illegal command from key 0%o\r\n", ch);
@@ -433,7 +508,24 @@
 				    "Error command = %d\n", cmdnum);
 		}
 #endif /* DEBUG_READ */
+		/* vi redo needs these way down the levels... */
+		el->el_state.thiscmd = cmdnum;
+		el->el_state.thisch = ch;
+		if (el->el_map.type == MAP_VI &&
+		    el->el_map.current == el->el_map.key &&
+		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
+			if (cmdnum == VI_DELETE_PREV_CHAR &&
+			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
+			    && isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
+				el->el_chared.c_redo.pos--;
+			else
+				*el->el_chared.c_redo.pos++ = ch;
+		}
 		retval = (*el->el_map.func[cmdnum]) (el, ch);
+#ifdef DEBUG_READ
+		(void) fprintf(el->el_errfile,
+			"Returned state %d\n", retval );
+#endif /* DEBUG_READ */
 
 		/* save the last command here */
 		el->el_state.lastcmd = cmdnum;
@@ -441,8 +533,6 @@
 		/* use any return value */
 		switch (retval) {
 		case CC_CURSOR:
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			re_refresh_cursor(el);
 			break;
 
@@ -452,29 +542,29 @@
 			/* FALLTHROUGH */
 
 		case CC_REFRESH:
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			re_refresh(el);
 			break;
 
 		case CC_REFRESH_BEEP:
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			re_refresh(el);
 			term_beep(el);
 			break;
 
 		case CC_NORM:	/* normal char */
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			break;
 
 		case CC_ARGHACK:	/* Suggested by Rich Salz */
 			/* <rsalz@pineapple.bbn.com> */
-			break;	/* keep going... */
+			continue;	/* keep going... */
 
 		case CC_EOF:	/* end of file typed */
-			num = 0;
+			if ((el->el_flags & UNBUFFERED) == 0)
+				num = 0;
+			else if (num == -1) {
+				*el->el_line.lastchar++ = CONTROL('d');
+				el->el_line.cursor = el->el_line.lastchar;
+				num = 1;
+			}
 			break;
 
 		case CC_NEWLINE:	/* normal end of line */
@@ -490,8 +580,6 @@
 			re_clear_display(el);	/* reset the display stuff */
 			ch_reset(el);	/* reset the input pointers */
 			re_refresh(el);	/* print the prompt again */
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			break;
 
 		case CC_ERROR:
@@ -500,20 +588,26 @@
 			(void) fprintf(el->el_errfile,
 			    "*** editor ERROR ***\r\n\n");
 #endif /* DEBUG_READ */
-			el->el_state.argument = 1;
-			el->el_state.doingarg = 0;
 			term_beep(el);
 			term__flush();
 			break;
 		}
+		el->el_state.argument = 1;
+		el->el_state.doingarg = 0;
+		el->el_chared.c_vcmd.action = NOP;
+		if (el->el_flags & UNBUFFERED)
+			break;
 	}
 
 	term__flush();		/* flush any buffered output */
-				/* make sure the tty is set up correctly */
-	(void) tty_cookedmode(el);
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_clr(el);
-	if (nread)
-		*nread = num;
+	/* make sure the tty is set up correctly */
+	if ((el->el_flags & UNBUFFERED) == 0) {
+		read_finish(el);
+		if (nread)
+			*nread = num;
+	} else {
+		if (nread)
+			*nread = el->el_line.lastchar - el->el_line.buffer;
+	}
 	return (num ? el->el_line.buffer : NULL);
 }
diff --exclude=CVS -ruN src.orig/lib/libedit/read.h src/lib/libedit/read.h
--- src.orig/lib/libedit/read.h	Wed Dec 31 17:00:00 1969
+++ src/lib/libedit/read.h	Wed Mar 30 21:13:40 2005
@@ -0,0 +1,59 @@
+/*	$NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Anthony Mallet.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * el.read.h: Character reading functions
+ */
+#ifndef	_h_el_read
+#define	_h_el_read
+
+typedef int (*el_rfunc_t)(EditLine *, char *);
+
+typedef struct el_read_t {
+	el_rfunc_t	read_char;	/* Function to read a character */
+} el_read_t;
+ 
+protected int		read_init(EditLine *);
+protected void		read_prepare(EditLine *);
+protected void		read_finish(EditLine *);
+protected int		el_read_setfn(EditLine *, el_rfunc_t);
+protected el_rfunc_t	el_read_getfn(EditLine *);
+
+#endif /* _h_el_read */
diff --exclude=CVS -ruN src.orig/lib/libedit/refresh.c src/lib/libedit/refresh.c
--- src.orig/lib/libedit/refresh.c	Mon Oct  1 17:00:28 2001
+++ src/lib/libedit/refresh.c	Thu Mar 31 17:55:30 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,21 +30,23 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: refresh.c,v 1.16 2001/01/10 07:45:42 jdolecek Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/refresh.c,v 1.9 2001/10/01 23:00:28 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/refresh.c,v 1.8 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * refresh.c: Lower level screen refreshing functions
  */
-#include "sys.h"
 #include <stdio.h>
+#include <ctype.h>
 #include <unistd.h>
 #include <string.h>
 
@@ -58,24 +58,24 @@
 private void	re_delete(EditLine *, char *, int, int, int);
 private void	re_fastputc(EditLine *, int);
 private void	re__strncopy(char *, char *, size_t);
-private void	re__copy_and_pad(char *, char *, size_t);
+private void	re__copy_and_pad(char *, const char *, size_t);
 
 #ifdef DEBUG_REFRESH
-private void	re_printstr(EditLine *, char *, char *, char *);
+private void	re_printstr(EditLine *, const char *, char *, char *);
 #define	__F el->el_errfile
 #define	ELRE_ASSERT(a, b, c)	do 				\
-				    if (a) {			\
+				    if (/*CONSTCOND*/ a) {	\
 					(void) fprintf b;	\
 					c;			\
 				    }				\
-				while (0)
+				while (/*CONSTCOND*/0)
 #define	ELRE_DEBUG(a, b)	ELRE_ASSERT(a,b,;)
 
 /* re_printstr():
  *	Print a string on the debugging pty
  */
 private void
-re_printstr(EditLine *el, char *str, char *f, char *t)
+re_printstr(EditLine *el, const char *str, char *f, char *t)
 {
 
 	ELRE_DEBUG(1, (__F, "%s:\"", str));
@@ -96,8 +96,6 @@
 re_addc(EditLine *el, int c)
 {
 
-	c = (unsigned char)c;
-
 	if (isprint(c)) {
 		re_putc(el, c, 1);
 		return;
@@ -119,11 +117,11 @@
 		}
 	} else if (iscntrl(c)) {
 		re_putc(el, '^', 1);
-		if (c == 0177)
+		if (c == '\177')
 			re_putc(el, '?', 1);
 		else
 		    /* uncontrolify it; works only for iso8859-1 like sets */
-			re_putc(el, (toascii(c) | 0100), 1);
+			re_putc(el, (c | 0100), 1);
 	} else {
 		re_putc(el, '\\', 1);
 		re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1);
@@ -208,6 +206,14 @@
 	el->el_refresh.r_cursor.h = 0;
 	el->el_refresh.r_cursor.v = 0;
 
+	if (el->el_line.cursor >= el->el_line.lastchar) {
+		if (el->el_map.current == el->el_map.alt
+		    && el->el_line.lastchar != el->el_line.buffer)
+			el->el_line.cursor = el->el_line.lastchar - 1;
+		else
+			el->el_line.cursor = el->el_line.lastchar;
+	}
+
 	cur.h = -1;		/* set flag in case I'm not set */
 	cur.v = 0;
 
@@ -317,7 +323,6 @@
 {
 
 	term_move_to_line(el, el->el_refresh.r_oldcv);
-	term__putc('\r');
 	term__putc('\n');
 	re_clear_display(el);
 	term__flush();
@@ -330,7 +335,8 @@
  */
 private void
 /*ARGSUSED*/
-re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num)
+re_insert(EditLine *el __attribute__((__unused__)),
+    char *d, int dat, int dlen, char *s, int num)
 {
 	char *a, *b;
 
@@ -373,7 +379,8 @@
  */
 private void
 /*ARGSUSED*/
-re_delete(EditLine *el, char *d, int dat, int dlen, int num)
+re_delete(EditLine *el __attribute__((__unused__)),
+    char *d, int dat, int dlen, int num)
 {
 	char *a, *b;
 
@@ -906,9 +913,9 @@
  *	Copy string and pad with spaces
  */
 private void
-re__copy_and_pad(char *dst, char *src, size_t width)
+re__copy_and_pad(char *dst, const char *src, size_t width)
 {
-	int i;
+	size_t i;
 
 	for (i = 0; i < width; i++) {
 		if (*src == '\0')
@@ -932,6 +939,14 @@
 	char *cp, c;
 	int h, v, th;
 
+	if (el->el_line.cursor >= el->el_line.lastchar) {
+		if (el->el_map.current == el->el_map.alt
+		    && el->el_line.lastchar != el->el_line.buffer)
+			el->el_line.cursor = el->el_line.lastchar - 1;
+		else
+			el->el_line.cursor = el->el_line.lastchar;
+	}
+
 	/* first we must find where the cursor is... */
 	h = el->el_prompt.p_pos.h;
 	v = el->el_prompt.p_pos.v;
@@ -939,7 +954,7 @@
 
 	/* do input buffer to el->el_line.cursor */
 	for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
-		c = (unsigned char)*cp;
+		c = *cp;
 		h++;		/* all chars at least this long */
 
 		if (c == '\n') {/* handle newline in data part too */
@@ -1034,7 +1049,7 @@
 	char c;
 	int rhdiff;
 
-	c = (unsigned char)el->el_line.cursor[-1];
+	c = el->el_line.cursor[-1];
 
 	if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
 		re_refresh(el);	/* too hard to handle */
@@ -1047,15 +1062,15 @@
 		return;
 	}			/* else (only do at end of line, no TAB) */
 	if (iscntrl((unsigned char) c)) {	/* if control char, do caret */
-		char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
+		char mc = (c == '\177') ? '?' : (c | 0100);
 		re_fastputc(el, '^');
 		re_fastputc(el, mc);
 	} else if (isprint((unsigned char) c)) {	/* normal char */
 		re_fastputc(el, c);
 	} else {
 		re_fastputc(el, '\\');
-		re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0'));
-		re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0'));
+		re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0'));
+		re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
 		re_fastputc(el, (c & 7) + '0');
 	}
 	term__flush();
diff --exclude=CVS -ruN src.orig/lib/libedit/refresh.h src/lib/libedit/refresh.h
--- src.orig/lib/libedit/refresh.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/refresh.h	Wed Mar 30 21:15:33 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)refresh.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: refresh.h,v 1.3 2000/09/04 22:06:32 lukem Exp $
- * $FreeBSD: src/lib/libedit/refresh.h,v 1.2 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
diff --exclude=CVS -ruN src.orig/lib/libedit/search.c src/lib/libedit/search.c
--- src.orig/lib/libedit/search.c	Mon Oct  1 17:00:29 2001
+++ src/lib/libedit/search.c	Thu Mar 31 17:55:39 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,21 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: search.c,v 1.10 2001/01/04 15:56:32 christos Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)search.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/search.c,v 1.9 2001/10/01 23:00:29 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/search.c,v 1.8 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * search.c: History and character search functions
  */
-#include "sys.h"
 #include <stdlib.h>
 #if defined(REGEX)
 #include <regex.h>
@@ -74,7 +73,8 @@
 	el->el_search.patlen = 0;
 	el->el_search.patdir = -1;
 	el->el_search.chacha = '\0';
-	el->el_search.chadir = -1;
+	el->el_search.chadir = CHAR_FWD;
+	el->el_search.chatflg = 0;
 	return (0);
 }
 
@@ -223,8 +223,11 @@
 		if (el->el_search.patlen == 0) {	/* first round */
 			pchar = ':';
 #ifdef ANCHOR
+#define	LEN	2
 			el->el_search.patbuf[el->el_search.patlen++] = '.';
 			el->el_search.patbuf[el->el_search.patlen++] = '*';
+#else
+#define	LEN	0
 #endif
 		}
 		done = redo = 0;
@@ -233,7 +236,7 @@
 		    *cp; *el->el_line.lastchar++ = *cp++)
 			continue;
 		*el->el_line.lastchar++ = pchar;
-		for (cp = &el->el_search.patbuf[1];
+		for (cp = &el->el_search.patbuf[LEN];
 		    cp < &el->el_search.patbuf[el->el_search.patlen];
 		    *el->el_line.lastchar++ = *cp++)
 			continue;
@@ -246,7 +249,7 @@
 		switch (el->el_map.current[(unsigned char) ch]) {
 		case ED_INSERT:
 		case ED_DIGIT:
-			if (el->el_search.patlen > EL_BUFSIZ - 3)
+			if (el->el_search.patlen >= EL_BUFSIZ - LEN)
 				term_beep(el);
 			else {
 				el->el_search.patbuf[el->el_search.patlen++] =
@@ -267,8 +270,9 @@
 			redo++;
 			break;
 
+		case EM_DELETE_PREV_CHAR:
 		case ED_DELETE_PREV_CHAR:
-			if (el->el_search.patlen > 1)
+			if (el->el_search.patlen > LEN)
 				done++;
 			else
 				term_beep(el);
@@ -283,17 +287,18 @@
 
 			case 0027:	/* ^W: Append word */
 			/* No can do if globbing characters in pattern */
-				for (cp = &el->el_search.patbuf[1];; cp++)
-				    if (cp >= &el->el_search.patbuf[el->el_search.patlen]) {
+				for (cp = &el->el_search.patbuf[LEN];; cp++)
+				    if (cp >= &el->el_search.patbuf[
+					el->el_search.patlen]) {
 					el->el_line.cursor +=
-					    el->el_search.patlen - 1;
+					    el->el_search.patlen - LEN - 1;
 					cp = c__next_word(el->el_line.cursor,
 					    el->el_line.lastchar, 1,
 					    ce__isword);
 					while (el->el_line.cursor < cp &&
 					    *el->el_line.cursor != '\n') {
-						if (el->el_search.patlen >
-						    EL_BUFSIZ - 3) {
+						if (el->el_search.patlen >=
+						    EL_BUFSIZ - LEN) {
 							term_beep(el);
 							break;
 						}
@@ -335,13 +340,13 @@
 			/* Can't search if unmatched '[' */
 			for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
 			    ch = ']';
-			    cp > el->el_search.patbuf;
+			    cp >= &el->el_search.patbuf[LEN];
 			    cp--)
 				if (*cp == '[' || *cp == ']') {
 					ch = *cp;
 					break;
 				}
-			if (el->el_search.patlen > 1 && ch != '[') {
+			if (el->el_search.patlen > LEN && ch != '[') {
 				if (redo && newdir == dir) {
 					if (pchar == '?') { /* wrap around */
 						el->el_history.eventno =
@@ -371,9 +376,8 @@
 				    '\0';
 				if (el->el_line.cursor < el->el_line.buffer ||
 				    el->el_line.cursor > el->el_line.lastchar ||
-				    (ret = ce_search_line(el,
-				    &el->el_search.patbuf[1],
-				    newdir)) == CC_ERROR) {
+				    (ret = ce_search_line(el, newdir))
+				    == CC_ERROR) {
 					/* avoid c_setpat */
 					el->el_state.lastcmd =
 					    (el_action_t) newdir;
@@ -386,11 +390,11 @@
 						    el->el_line.lastchar :
 						    el->el_line.buffer;
 						(void) ce_search_line(el,
-						    &el->el_search.patbuf[1],
 						    newdir);
 					}
 				}
-				el->el_search.patbuf[--el->el_search.patlen] =
+				el->el_search.patlen -= LEN;
+				el->el_search.patbuf[el->el_search.patlen] =
 				    '\0';
 				if (ret == CC_ERROR) {
 					term_beep(el);
@@ -446,29 +450,20 @@
 	char tmpbuf[EL_BUFSIZ];
 	int tmplen;
 
-	tmplen = 0;
 #ifdef ANCHOR
-	tmpbuf[tmplen++] = '.';
-	tmpbuf[tmplen++] = '*';
+	tmpbuf[0] = '.';
+	tmpbuf[1] = '*';
 #endif
+	tmplen = LEN;
 
-	el->el_line.buffer[0] = '\0';
-	el->el_line.lastchar = el->el_line.buffer;
-	el->el_line.cursor = el->el_line.buffer;
 	el->el_search.patdir = dir;
 
-	c_insert(el, 2);	/* prompt + '\n' */
-	*el->el_line.cursor++ = '\n';
-	*el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?';
-	re_refresh(el);
+	tmplen = c_gets(el, &tmpbuf[LEN],
+		dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
+	if (tmplen == -1)
+		return CC_REFRESH;
 
-#ifdef ANCHOR
-#define	LEN	2
-#else
-#define	LEN	0
-#endif
-
-	tmplen = c_gets(el, &tmpbuf[LEN]) + LEN;
+	tmplen += LEN;
 	ch = tmpbuf[tmplen];
 	tmpbuf[tmplen] = '\0';
 
@@ -477,9 +472,6 @@
 		 * Use the old pattern, but wild-card it.
 		 */
 		if (el->el_search.patlen == 0) {
-			el->el_line.buffer[0] = '\0';
-			el->el_line.lastchar = el->el_line.buffer;
-			el->el_line.cursor = el->el_line.buffer;
 			re_refresh(el);
 			return (CC_ERROR);
 		}
@@ -510,19 +502,15 @@
 	el->el_state.lastcmd = (el_action_t) dir;	/* avoid c_setpat */
 	el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
 	if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
-		ed_search_next_history(el, 0)) == CC_ERROR) {
+	    ed_search_next_history(el, 0)) == CC_ERROR) {
 		re_refresh(el);
 		return (CC_ERROR);
-	} else {
-		if (ch == 0033) {
-			re_refresh(el);
-			*el->el_line.lastchar++ = '\n';
-			*el->el_line.lastchar = '\0';
-			re_goto_bottom(el);
-			return (CC_NEWLINE);
-		} else
-			return (CC_REFRESH);
 	}
+	if (ch == 0033) {
+		re_refresh(el);
+		return ed_newline(el, 0);
+	}
+	return (CC_REFRESH);
 }
 
 
@@ -530,24 +518,39 @@
  *	Look for a pattern inside a line
  */
 protected el_action_t
-ce_search_line(EditLine *el, char *pattern, int dir)
+ce_search_line(EditLine *el, int dir)
 {
-	char *cp;
+	char *cp = el->el_line.cursor;
+	char *pattern = el->el_search.patbuf;
+	char oc, *ocp;
+#ifdef ANCHOR
+	ocp = &pattern[1];
+	oc = *ocp;
+	*ocp = '^';
+#else
+	ocp = pattern;
+	oc = *ocp;
+#endif
 
 	if (dir == ED_SEARCH_PREV_HISTORY) {
-		for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--)
-			if (el_match(cp, pattern)) {
+		for (; cp >= el->el_line.buffer; cp--) {
+			if (el_match(cp, ocp)) {
+				*ocp = oc;
 				el->el_line.cursor = cp;
 				return (CC_NORM);
 			}
+		}
+		*ocp = oc;
 		return (CC_ERROR);
 	} else {
-		for (cp = el->el_line.cursor; *cp != '\0' &&
-		    cp < el->el_line.limit; cp++)
-			if (el_match(cp, pattern)) {
+		for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
+			if (el_match(cp, ocp)) {
+				*ocp = oc;
 				el->el_line.cursor = cp;
 				return (CC_NORM);
 			}
+		}
+		*ocp = oc;
 		return (CC_ERROR);
 	}
 }
@@ -579,69 +582,53 @@
 }
 
 
-/* cv_csearch_back():
- *	Vi character search reverse
+/* cv_csearch():
+ *	Vi character search
  */
 protected el_action_t
-cv_csearch_back(EditLine *el, int ch, int count, int tflag)
+cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
 {
 	char *cp;
 
-	cp = el->el_line.cursor;
-	while (count--) {
-		if (*cp == ch)
-			cp--;
-		while (cp > el->el_line.buffer && *cp != ch)
-			cp--;
-	}
-
-	if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch))
-		return (CC_ERROR);
-
-	if (*cp == ch && tflag)
-		cp++;
-
-	el->el_line.cursor = cp;
+	if (ch == 0)
+		return CC_ERROR;
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
-		el->el_line.cursor++;
-		cv_delfini(el);
-		return (CC_REFRESH);
+	if (ch == -1) {
+		char c;
+		if (el_getc(el, &c) != 1)
+			return ed_end_of_file(el, 0);
+		ch = c;
 	}
-	re_refresh_cursor(el);
-	return (CC_NORM);
-}
 
-
-/* cv_csearch_fwd():
- *	Vi character search forward
- */
-protected el_action_t
-cv_csearch_fwd(EditLine *el, int ch, int count, int tflag)
-{
-	char *cp;
+	/* Save for ';' and ',' commands */
+	el->el_search.chacha = ch;
+	el->el_search.chadir = direction;
+	el->el_search.chatflg = tflag;
 
 	cp = el->el_line.cursor;
 	while (count--) {
 		if (*cp == ch)
-			cp++;
-		while (cp < el->el_line.lastchar && *cp != ch)
-			cp++;
+			cp += direction;
+		for (;;cp += direction) {
+			if (cp >= el->el_line.lastchar)
+				return CC_ERROR;
+			if (cp < el->el_line.buffer)
+				return CC_ERROR;
+			if (*cp == ch)
+				break;
+		}
 	}
 
-	if (cp >= el->el_line.lastchar)
-		return (CC_ERROR);
-
-	if (*cp == ch && tflag)
-		cp--;
+	if (tflag)
+		cp -= direction;
 
 	el->el_line.cursor = cp;
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
-		el->el_line.cursor++;
+	if (el->el_chared.c_vcmd.action != NOP) {
+		if (direction > 0)
+			el->el_line.cursor++;
 		cv_delfini(el);
-		return (CC_REFRESH);
+		return CC_REFRESH;
 	}
-	re_refresh_cursor(el);
-	return (CC_NORM);
+	return CC_CURSOR;
 }
diff --exclude=CVS -ruN src.orig/lib/libedit/search.h src/lib/libedit/search.h
--- src.orig/lib/libedit/search.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/search.h	Wed Mar 30 21:16:30 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)search.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: search.h,v 1.4 1999/07/02 15:21:27 simonb Exp $
- * $FreeBSD: src/lib/libedit/search.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -52,6 +49,7 @@
 	int	 patdir;		/* Direction of the last search	*/
 	int	 chadir;		/* Character search direction	*/
 	char	 chacha;		/* Character we are looking for	*/
+	char	 chatflg;		/* 0 if f, 1 if t */
 } el_search_t;
 
 
@@ -62,9 +60,8 @@
 protected void		c_setpat(EditLine *);
 protected el_action_t	ce_inc_search(EditLine *, int);
 protected el_action_t	cv_search(EditLine *, int);
-protected el_action_t	ce_search_line(EditLine *, char *, int);
+protected el_action_t	ce_search_line(EditLine *, int);
 protected el_action_t	cv_repeat_srch(EditLine *, int);
-protected el_action_t	cv_csearch_back(EditLine *, int, int, int);
-protected el_action_t	cv_csearch_fwd(EditLine *, int, int, int);
+protected el_action_t	cv_csearch(EditLine *, int, int, int, int);
 
 #endif /* _h_el_search */
diff --exclude=CVS -ruN src.orig/lib/libedit/sig.c src/lib/libedit/sig.c
--- src.orig/lib/libedit/sig.c	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/sig.c	Thu Mar 31 17:55:44 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,22 +30,23 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: sig.c,v 1.7 2001/01/04 15:55:03 christos Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/sig.c,v 1.6 2001/10/01 08:41:25 obrien Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * sig.c: Signal handling stuff.
  *	  our policy is to trap all signals, set a good state
  *	  and pass the ball to our caller.
  */
-#include "sys.h"
 #include "el.h"
 #include <stdlib.h>
 
@@ -119,9 +118,9 @@
 #undef	_DO
 	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
 
-#define	SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
+#define	SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
 
-	el->el_signal = (sig_t *) el_malloc(SIGSIZE);
+	el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
 	if (el->el_signal == NULL)
 		return (-1);
 	for (i = 0; sighdl[i] != -1; i++)
@@ -161,7 +160,7 @@
 	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
 
 	for (i = 0; sighdl[i] != -1; i++) {
-		sig_t s;
+		el_signalhandler_t s;
 		/* This could happen if we get interrupted */
 		if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
 			el->el_signal[i] = s;
diff --exclude=CVS -ruN src.orig/lib/libedit/sig.h src/lib/libedit/sig.h
--- src.orig/lib/libedit/sig.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/sig.h	Wed Mar 30 21:18:04 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)sig.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: sig.h,v 1.2 1997/01/11 06:48:11 lukem Exp $
- * $FreeBSD: src/lib/libedit/sig.h,v 1.2 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -62,7 +59,8 @@
 	_DO(SIGCONT)	\
 	_DO(SIGWINCH)
 
-typedef sig_t	*el_signal_t;
+typedef void (*el_signalhandler_t)(int);
+typedef el_signalhandler_t *el_signal_t;
 
 protected void	sig_end(EditLine*);
 protected int	sig_init(EditLine*);
diff --exclude=CVS -ruN src.orig/lib/libedit/sys.h src/lib/libedit/sys.h
--- src.orig/lib/libedit/sys.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/sys.h	Wed Mar 30 21:18:54 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)sys.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: sys.h,v 1.3 1997/01/11 06:48:12 lukem Exp $
- * $FreeBSD: src/lib/libedit/sys.h,v 1.4 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -44,6 +41,24 @@
 #ifndef _h_sys
 #define	_h_sys
 
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__)  || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+# define __attribute__(A)
+#endif
+
+#ifndef __BEGIN_DECLS
+# ifdef  __cplusplus
+#  define __BEGIN_DECLS  extern "C" {
+#  define __END_DECLS    }
+# else
+#  define __BEGIN_DECLS
+#  define __END_DECLS
+# endif
+#endif
+ 
 #ifndef public
 # define public		/* Externally visible functions/variables */
 #endif
@@ -57,8 +72,6 @@
 			/* When we want to hide everything	*/
 #endif
 
-#include <sys/cdefs.h>
-
 #ifndef _PTR_T
 # define _PTR_T
 typedef void	*ptr_t;
@@ -71,23 +84,42 @@
 
 #include <stdio.h>
 
+#ifndef HAVE_STRLCAT
+#define	strlcat libedit_strlcat
+size_t	strlcat(char *dst, const char *src, size_t size);
+#endif
+
+#ifndef HAVE_STRLCPY
+#define	strlcpy libedit_strlcpy
+size_t	strlcpy(char *dst, const char *src, size_t size);
+#endif
+
+#ifndef HAVE_FGETLN
+#define	fgetln libedit_fgetln
+char	*fgetln(FILE *fp, size_t *len);
+#endif
+
 #define	REGEX		/* Use POSIX.2 regular expression functions */
 #undef	REGEXP		/* Use UNIX V8 regular expression functions */
 
-#ifdef SUNOS
+#ifdef notdef
 # undef REGEX
 # undef REGEXP
 # include <malloc.h>
-typedef void (*sig_t)(int);
 # ifdef __GNUC__
 /*
  * Broken hdrs.
  */
+extern int	tgetent(const char *bp, char *name);
+extern int	tgetflag(const char *id);
+extern int	tgetnum(const char *id);
+extern char    *tgetstr(const char *id, char **area);
+extern char    *tgoto(const char *cap, int col, int row);
+extern int	tputs(const char *str, int affcnt, int (*putc)(int));
 extern char    *getenv(const char *);
 extern int	fprintf(FILE *, const char *, ...);
 extern int	sigsetmask(int);
 extern int	sigblock(int);
-extern int	ioctl(int, int, void *);
 extern int	fputc(int, FILE *);
 extern int	fgetc(FILE *);
 extern int	fflush(FILE *);
@@ -96,7 +128,6 @@
 extern int	errno, sys_nerr;
 extern char	*sys_errlist[];
 extern void	perror(const char *);
-extern int	read(int, const char*, int);
 #  include <string.h>
 #  define strerror(e)	sys_errlist[e]
 # endif
diff --exclude=CVS -ruN src.orig/lib/libedit/term.c src/lib/libedit/term.c
--- src.orig/lib/libedit/term.c	Thu Jan 24 06:54:19 2002
+++ src/lib/libedit/term.c	Thu Mar 31 17:55:56 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,28 +30,41 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: term.c,v 1.31 2001/01/10 22:42:56 jdolecek Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)term.c	8.2 (Berkeley) 4/30/95";
+#else
+__RCSID("$NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/term.c,v 1.16 2002/01/24 13:54:19 obrien Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * term.c: Editor/termcap-curses interface
  *	   We have to declare a static variable here, since the
  *	   termcap putchar routine does not take an argument!
  */
-#include "sys.h"
 #include <stdio.h>
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
+#ifdef HAVE_TERMCAP_H
 #include <termcap.h>
+#endif
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#endif
+/* Solaris's term.h does horrid things. */
+#if (defined(HAVE_TERM_H) && !defined(SUNOS))
+#include <term.h>
+#endif
 #include <sys/types.h>
 #include <sys/ioctl.h>
 
@@ -258,7 +269,7 @@
 private int	term_rebuffer_display(EditLine *);
 private void	term_free_display(EditLine *);
 private int	term_alloc_display(EditLine *);
-private void	term_alloc(EditLine *, const struct termcapstr *, char *);
+private void	term_alloc(EditLine *, const struct termcapstr *, const char *);
 private void	term_init_arrow(EditLine *);
 private void	term_reset_arrow(EditLine *);
 
@@ -338,11 +349,11 @@
 		return (-1);
 	(void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
 	term_outfile = el->el_outfile;
+	(void) term_set(el, NULL);
 	term_init_arrow(el);
-	if (term_set(el, NULL) == -1)
-		return (-1);
 	return (0);
 }
+
 /* term_end():
  *	Clean up the terminal stuff
  */
@@ -359,6 +370,8 @@
 	el->el_term.t_str = NULL;
 	el_free((ptr_t) el->el_term.t_val);
 	el->el_term.t_val = NULL;
+	el_free((ptr_t) el->el_term.t_fkey);
+	el->el_term.t_fkey = NULL;
 	term_free_display(el);
 }
 
@@ -367,7 +380,7 @@
  *	Maintain a string pool for termcap strings
  */
 private void
-term_alloc(EditLine *el, const struct termcapstr *t, char *cap)
+term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
 {
 	char termbuf[TC_BUFSIZE];
 	int tlen, clen;
@@ -635,7 +648,8 @@
 				 * from col 0
 				 */
 				if (EL_CAN_TAB ?
-				    (-del > (((unsigned int) where >> 3) +
+				    ((unsigned int)-del >
+				    (((unsigned int) where >> 3) +
 				     (where & 07)))
 				    : (-del > where)) {
 					term__putc('\r');	/* do a CR */
@@ -655,7 +669,7 @@
  *	Overstrike num characters
  */
 protected void
-term_overwrite(EditLine *el, char *cp, int n)
+term_overwrite(EditLine *el, const char *cp, int n)
 {
 	if (n <= 0)
 		return;		/* catch bugs */
@@ -863,12 +877,18 @@
 }
 #endif
 
+protected void
+term_get(EditLine *el, const char **term)
+{
+	*term = el->el_term.t_name;
+}
+
 
 /* term_set():
  *	Read in the terminal capabilities from the requested terminal
  */
 protected int
-term_set(EditLine *el, char *term)
+term_set(EditLine *el, const char *term)
 {
 	int i;
 	char buf[TC_BUFSIZE];
@@ -924,8 +944,11 @@
 		/* Get the size */
 		Val(T_co) = tgetnum("co");
 		Val(T_li) = tgetnum("li");
-		for (t = tstr; t->name != NULL; t++)
-			term_alloc(el, t, tgetstr(t->name, &area));
+		for (t = tstr; t->name != NULL; t++) {
+			/* XXX: some systems tgetstr needs non const */
+			term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
+			    &area));
+		}
 	}
 
 	if (Val(T_co) < 2)
@@ -944,6 +967,7 @@
 		return (-1);
 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
 	term_bind_arrow(el);
+	el->el_term.t_name = term;
 	return (i <= 0 ? -1 : 0);
 }
 
@@ -1058,8 +1082,6 @@
 	static const char strD[] = {033, '[', 'D', '\0'};
 	static const char strH[] = {033, '[', 'H', '\0'};
 	static const char strF[] = {033, '[', 'F', '\0'};
-	static const char str1[] = {033, '[', '1', '~', '\0'};
-	static const char str4[] = {033, '[', '4', '~', '\0'};
 	static const char stOA[] = {033, 'O', 'A', '\0'};
 	static const char stOB[] = {033, 'O', 'B', '\0'};
 	static const char stOC[] = {033, 'O', 'C', '\0'};
@@ -1073,8 +1095,6 @@
 	key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
 	key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
 	key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-	key_add(el, str1, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-	key_add(el, str4, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
 	key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
 	key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
 	key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
@@ -1089,8 +1109,6 @@
 		key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
 		key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
 		key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-		key_add(el, &str1[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-		key_add(el, &str4[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
 		key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
 		key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
 		key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
@@ -1105,7 +1123,7 @@
  *	Set an arrow key binding
  */
 protected int
-term_set_arrow(EditLine *el, char *name, key_value_t *fun, int type)
+term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
 {
 	fkey_t *arrow = el->el_term.t_fkey;
 	int i;
@@ -1124,7 +1142,7 @@
  *	Clear an arrow key binding
  */
 protected int
-term_clear_arrow(EditLine *el, char *name)
+term_clear_arrow(EditLine *el, const char *name)
 {
 	fkey_t *arrow = el->el_term.t_fkey;
 	int i;
@@ -1142,7 +1160,7 @@
  *	Print the arrow key bindings
  */
 protected void
-term_print_arrow(EditLine *el, char *name)
+term_print_arrow(EditLine *el, const char *name)
 {
 	int i;
 	fkey_t *arrow = el->el_term.t_fkey;
@@ -1239,7 +1257,8 @@
  */
 protected int
 /*ARGSUSED*/
-term_telltc(EditLine *el, int argc, char **argv)
+term_telltc(EditLine *el, int argc __attribute__((__unused__)), 
+    const char **argv __attribute__((__unused__)))
 {
 	const struct termcapstr *t;
 	char **ts;
@@ -1274,11 +1293,12 @@
  */
 protected int
 /*ARGSUSED*/
-term_settc(EditLine *el, int argc, char **argv)
+term_settc(EditLine *el, int argc __attribute__((__unused__)),
+    const char **argv)
 {
 	const struct termcapstr *ts;
 	const struct termcapval *tv;
-	char *what, *how;
+	const char *what, *how;
 
 	if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
 		return (-1);
@@ -1350,7 +1370,8 @@
  */
 protected int
 /*ARGSUSED*/
-term_echotc(EditLine *el, int argc, char **argv)
+term_echotc(EditLine *el, int argc __attribute__((__unused__)),
+    const char **argv)
 {
 	char *cap, *scap, *ep;
 	int arg_need, arg_cols, arg_rows;
@@ -1409,7 +1430,7 @@
 			}
 		(void) fprintf(el->el_outfile, fmtd, 0);
 #else
-		(void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed);
+		(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
 #endif
 		return (0);
 	} else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
@@ -1428,8 +1449,10 @@
 			scap = el->el_term.t_str[t - tstr];
 			break;
 		}
-	if (t->name == NULL)
-		scap = tgetstr(*argv, &area);
+	if (t->name == NULL) {
+		/* XXX: some systems tgetstr needs non const */
+		scap = tgetstr(strchr(*argv, **argv), &area);
+	}
 	if (!scap || scap[0] == '\0') {
 		if (!silent)
 			(void) fprintf(el->el_errfile,
diff --exclude=CVS -ruN src.orig/lib/libedit/term.h src/lib/libedit/term.h
--- src.orig/lib/libedit/term.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/term.h	Wed Mar 30 21:20:05 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: term.h,v 1.16 2005/03/15 00:10:40 christos Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)term.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: term.h,v 1.11 2000/11/11 22:18:58 christos Exp $
- * $FreeBSD: src/lib/libedit/term.h,v 1.5 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -47,13 +44,14 @@
 #include "histedit.h"
 
 typedef struct {		/* Symbolic function key bindings	*/
-	char		*name;	/* name of the key			*/
+	const char	*name;	/* name of the key			*/
 	int		 key;	/* Index in termcap table		*/
 	key_value_t	 fun;	/* Function bound to it			*/
 	int		 type;	/* Type of function			*/
 } fkey_t;
 
 typedef struct {
+	const char *t_name;		/* the terminal name	*/
 	coord_t	  t_size;		/* # lines and cols	*/
 	int	  t_flags;
 #define	TERM_CAN_INSERT		0x001	/* Has insert cap	*/
@@ -87,7 +85,7 @@
 protected void	term_move_to_line(EditLine *, int);
 protected void	term_move_to_char(EditLine *, int);
 protected void	term_clear_EOL(EditLine *, int);
-protected void	term_overwrite(EditLine *, char *, int);
+protected void	term_overwrite(EditLine *, const char *, int);
 protected void	term_insertwrite(EditLine *, char *, int);
 protected void	term_deletechars(EditLine *, int);
 protected void	term_clear_screen(EditLine *);
@@ -96,14 +94,15 @@
 protected int	term_get_size(EditLine *, int *, int *);
 protected int	term_init(EditLine *);
 protected void	term_bind_arrow(EditLine *);
-protected void	term_print_arrow(EditLine *, char *);
-protected int	term_clear_arrow(EditLine *, char *);
-protected int	term_set_arrow(EditLine *, char *, key_value_t *, int);
+protected void	term_print_arrow(EditLine *, const char *);
+protected int	term_clear_arrow(EditLine *, const char *);
+protected int	term_set_arrow(EditLine *, const char *, key_value_t *, int);
 protected void	term_end(EditLine *);
-protected int	term_set(EditLine *, char *);
-protected int	term_settc(EditLine *, int, char **);
-protected int	term_telltc(EditLine *, int, char **);
-protected int	term_echotc(EditLine *, int, char **);
+protected void	term_get(EditLine *, const char **);
+protected int	term_set(EditLine *, const char *);
+protected int	term_settc(EditLine *, int, const char **);
+protected int	term_telltc(EditLine *, int, const char **);
+protected int	term_echotc(EditLine *, int, const char **);
 protected int	term__putc(int);
 protected void	term__flush(void);
 
@@ -117,6 +116,7 @@
 #define	EL_CAN_CEOL		(EL_FLAGS & TERM_CAN_CEOL)
 #define	EL_CAN_TAB		(EL_FLAGS & TERM_CAN_TAB)
 #define	EL_CAN_ME		(EL_FLAGS & TERM_CAN_ME)
+#define EL_CAN_UP		(EL_FLAGS & TERM_CAN_UP)
 #define	EL_HAS_META		(EL_FLAGS & TERM_HAS_META)
 #define	EL_HAS_AUTO_MARGINS	(EL_FLAGS & TERM_HAS_AUTO_MARGINS)
 #define	EL_HAS_MAGIC_MARGINS	(EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
diff --exclude=CVS -ruN src.orig/lib/libedit/tokenizer.c src/lib/libedit/tokenizer.c
--- src.orig/lib/libedit/tokenizer.c	Mon Oct  1 17:00:29 2001
+++ src/lib/libedit/tokenizer.c	Thu Mar 31 17:56:01 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,23 +30,24 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: tokenizer.c,v 1.6 2000/09/04 22:06:33 lukem Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)tokenizer.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/tokenizer.c,v 1.6 2001/10/01 23:00:29 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libedit/tokenizer.c,v 1.5 2001/10/01 08:41:25 obrien Exp $");
 
 /*
  * tokenize.c: Bourne shell like tokenizer
  */
-#include "sys.h"
 #include <string.h>
 #include <stdlib.h>
-#include "tokenizer.h"
+#include "histedit.h"
 
 typedef enum {
 	Q_none, Q_single, Q_double, Q_one, Q_doubleone
@@ -62,10 +61,10 @@
 #define	WINCR		20
 #define	AINCR		10
 
+#define	tok_strdup(a)		strdup(a)
 #define	tok_malloc(a)		malloc(a)
 #define	tok_free(a)		free(a)
 #define	tok_realloc(a, b)	realloc(a, b)
-#define tok_reallocf(a, b)	reallocf(a, b)
 
 
 struct tokenizer {
@@ -108,16 +107,29 @@
 {
 	Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
 
-	tok->ifs = strdup(ifs ? ifs : IFS);
+	if (tok == NULL)
+		return NULL;
+	tok->ifs = tok_strdup(ifs ? ifs : IFS);
+	if (tok->ifs == NULL) {
+		tok_free((ptr_t)tok);
+		return NULL;
+	}
 	tok->argc = 0;
 	tok->amax = AINCR;
 	tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
-	if (tok->argv == NULL)
-		return (NULL);
+	if (tok->argv == NULL) {
+		tok_free((ptr_t)tok->ifs);
+		tok_free((ptr_t)tok);
+		return NULL;
+	}
 	tok->argv[0] = NULL;
 	tok->wspace = (char *) tok_malloc(WINCR);
-	if (tok->wspace == NULL)
-		return (NULL);
+	if (tok->wspace == NULL) {
+		tok_free((ptr_t)tok->argv);
+		tok_free((ptr_t)tok->ifs);
+		tok_free((ptr_t)tok);
+		return NULL;
+	}
 	tok->wmax = tok->wspace + WINCR;
 	tok->wstart = tok->wspace;
 	tok->wptr = tok->wspace;
@@ -159,21 +171,39 @@
 
 
 /* tok_line():
- *	Bourne shell like tokenizing
- *	Return:
- *		-1: Internal error
- *		 3: Quoted return
- *		 2: Unmatched double quote
- *		 1: Unmatched single quote
- *		 0: Ok
+ *	Bourne shell (sh(1)) like tokenizing
+ *	Arguments:
+ *		tok	current tokenizer state (setup with tok_init())
+ *		line	line to parse
+ *	Returns:
+ *		-1	Internal error
+ *		 3	Quoted return
+ *		 2	Unmatched double quote
+ *		 1	Unmatched single quote
+ *		 0	Ok
+ *	Modifies (if return value is 0):
+ *		argc	number of arguments
+ *		argv	argument array
+ *		cursorc	if !NULL, argv element containing cursor
+ *		cursorv	if !NULL, offset in argv[cursorc] of cursor
  */
 public int
-tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv)
+tok_line(Tokenizer *tok, const LineInfo *line,
+    int *argc, const char ***argv, int *cursorc, int *cursoro)
 {
 	const char *ptr;
+	int cc, co;
 
-	for (;;) {
-		switch (*(ptr = line++)) {
+	cc = co = -1;
+	ptr = line->buffer;
+	for (ptr = line->buffer; ;ptr++) {
+		if (ptr >= line->lastchar)
+			ptr = "";
+		if (ptr == line->cursor) {
+			cc = tok->argc;
+			co = tok->wptr - tok->wstart;
+		}
+		switch (*ptr) {
 		case '\'':
 			tok->flags |= TOK_KEEP;
 			tok->flags &= ~TOK_EAT;
@@ -272,10 +302,7 @@
 			tok->flags &= ~TOK_EAT;
 			switch (tok->quote) {
 			case Q_none:
-				tok_finish(tok);
-				*argv = tok->argv;
-				*argc = tok->argc;
-				return (0);
+				goto tok_line_outok;
 
 			case Q_single:
 			case Q_double:
@@ -305,10 +332,7 @@
 					tok->flags &= ~TOK_EAT;
 					return (3);
 				}
-				tok_finish(tok);
-				*argv = tok->argv;
-				*argc = tok->argc;
-				return (0);
+				goto tok_line_outok;
 
 			case Q_single:
 				return (1);
@@ -368,29 +392,57 @@
 		if (tok->wptr >= tok->wmax - 4) {
 			size_t size = tok->wmax - tok->wspace + WINCR;
 			char *s = (char *) tok_realloc(tok->wspace, size);
-			/* SUPPRESS 22 */
-			int offs = s - tok->wspace;
 			if (s == NULL)
 				return (-1);
 
-			if (offs != 0) {
+			if (s != tok->wspace) {
 				int i;
-				for (i = 0; i < tok->argc; i++)
-					tok->argv[i] = tok->argv[i] + offs;
-				tok->wptr = tok->wptr + offs;
-				tok->wstart = tok->wstart + offs;
-				tok->wmax = s + size;
+				for (i = 0; i < tok->argc; i++) {
+				    tok->argv[i] =
+					(tok->argv[i] - tok->wspace) + s;
+				}
+				tok->wptr = (tok->wptr - tok->wspace) + s;
+				tok->wstart = (tok->wstart - tok->wspace) + s;
 				tok->wspace = s;
 			}
+			tok->wmax = s + size;
 		}
 		if (tok->argc >= tok->amax - 4) {
 			char **p;
 			tok->amax += AINCR;
-			p = (char **) tok_reallocf(tok->argv,
+			p = (char **) tok_realloc(tok->argv,
 			    tok->amax * sizeof(char *));
 			if (p == NULL)
 				return (-1);
 			tok->argv = p;
 		}
 	}
+ tok_line_outok:
+	if (cc == -1 && co == -1) {
+		cc = tok->argc;
+		co = tok->wptr - tok->wstart;
+	}
+	if (cursorc != NULL)
+		*cursorc = cc;
+	if (cursoro != NULL)
+		*cursoro = co;
+	tok_finish(tok);
+	*argv = (const char **)tok->argv;
+	*argc = tok->argc;
+	return (0);
+}
+
+/* tok_str():
+ *	Simpler version of tok_line, taking a NUL terminated line
+ *	and splitting into words, ignoring cursor state.
+ */
+public int
+tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+{
+	LineInfo li;
+
+	memset(&li, 0, sizeof(li));
+	li.buffer = line;
+	li.cursor = li.lastchar = strchr(line, '\0');
+	return (tok_line(tok, &li, argc, argv, NULL, NULL));
 }
diff --exclude=CVS -ruN src.orig/lib/libedit/tokenizer.h src/lib/libedit/tokenizer.h
--- src.orig/lib/libedit/tokenizer.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/tokenizer.h	Wed Dec 31 17:00:00 1969
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)tokenizer.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: tokenizer.h,v 1.3 1999/07/02 15:21:27 simonb Exp $
- * $FreeBSD: src/lib/libedit/tokenizer.h,v 1.3 2001/10/01 08:41:25 obrien Exp $
- */
-
-/*
- * tokenizer.h: Header file for tokenizer routines
- */
-#ifndef _h_tokenizer
-#define	_h_tokenizer
-
-typedef struct tokenizer Tokenizer;
-
-Tokenizer	*tok_init(const char *);
-void		 tok_reset(Tokenizer *);
-void		 tok_end(Tokenizer *);
-int		 tok_line(Tokenizer *, const char *, int *, char ***);
-
-#endif /* _h_tokenizer */
diff --exclude=CVS -ruN src.orig/lib/libedit/tty.c src/lib/libedit/tty.c
--- src.orig/lib/libedit/tty.c	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/tty.c	Thu Mar 31 17:56:07 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,22 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: tty.c,v 1.14 2001/01/09 17:31:04 jdolecek Exp $
  */
 
+#include "config.h"
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)tty.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/tty.c,v 1.7 2001/10/01 08:41:25 obrien Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * tty.c: tty interface stuff
  */
-#include "sys.h"
+#include <assert.h>
 #include "tty.h"
 #include "el.h"
 
@@ -58,7 +58,7 @@
 typedef struct ttymap_t {
 	int nch, och;		/* Internal and termio rep of chars */
 	el_action_t bind[3];	/* emacs, vi, and vi-cmd */
-}        ttymap_t;
+} ttymap_t;
 
 
 private const ttyperm_t ttyperm = {
@@ -122,11 +122,11 @@
 private const ttymap_t tty_map[] = {
 #ifdef VERASE
 	{C_ERASE, VERASE,
-	{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 #endif /* VERASE */
 #ifdef VERASE2
 	{C_ERASE2, VERASE2,
-	{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 #endif /* VERASE2 */
 #ifdef VKILL
 	{C_KILL, VKILL,
@@ -453,6 +453,7 @@
 #define	tty__geteightbit(td)	(((td)->c_cflag & CSIZE) == CS8)
 #define	tty__cooked_mode(td)	((td)->c_lflag & ICANON)
 
+private int	tty__getcharindex(int);
 private void	tty__getchar(struct termios *, unsigned char *);
 private void	tty__setchar(struct termios *, unsigned char *);
 private speed_t	tty__getspeed(struct termios *);
@@ -485,6 +486,18 @@
 	el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
 
+	el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
+	el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
+
+	el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
+	el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
+
+	el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
+	el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
+
+	el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
+	el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
+
 	/*
          * Reset the tty chars to reasonable defaults
          * If they are disabled, then enable them.
@@ -508,7 +521,17 @@
 					el->el_tty.t_c[EX_IO][rst] =
 					    el->el_tty.t_c[TS_IO][rst];
 		}
-	}
+		tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
+		if (tty_setty(el, &el->el_tty.t_ex) == -1) {
+#ifdef DEBUG_TTY
+			(void) fprintf(el->el_errfile,
+			    "tty_setup: tty_setty: %s\n",
+			    strerror(errno));
+#endif /* DEBUG_TTY */
+			return (-1);
+		}
+	} else
+		tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 
 	el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
 	el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
@@ -544,7 +567,7 @@
  */
 protected void
 /*ARGSUSED*/
-tty_end(EditLine *el)
+tty_end(EditLine *el __attribute__((__unused__)))
 {
 
 	/* XXX: Maybe reset to an initial state? */
@@ -564,6 +587,113 @@
 	return (spd);
 }
 
+/* tty__getspeed():
+ *	Return the index of the asked char in the c_cc array
+ */
+private int
+tty__getcharindex(int i)
+{
+	switch (i) {
+#ifdef VINTR
+	case C_INTR:
+		return VINTR;
+#endif /* VINTR */
+#ifdef VQUIT
+	case C_QUIT:
+		return VQUIT;
+#endif /* VQUIT */
+#ifdef VERASE
+	case C_ERASE:
+		return VERASE;
+#endif /* VERASE */
+#ifdef VKILL
+	case C_KILL:
+		return VKILL;
+#endif /* VKILL */
+#ifdef VEOF
+	case C_EOF:
+		return VEOF;
+#endif /* VEOF */
+#ifdef VEOL
+	case C_EOL:
+		return VEOL;
+#endif /* VEOL */
+#ifdef VEOL2
+	case C_EOL2:
+		return VEOL2;
+#endif /* VEOL2 */
+#ifdef VSWTCH
+	case C_SWTCH:
+		return VSWTCH;
+#endif /* VSWTCH */
+#ifdef VDSWTCH
+	case C_DSWTCH:
+		return VDSWTCH;
+#endif /* VDSWTCH */
+#ifdef VERASE2
+	case C_ERASE2:
+		return VERASE2;
+#endif /* VERASE2 */
+#ifdef VSTART
+	case C_START:
+		return VSTART;
+#endif /* VSTART */
+#ifdef VSTOP
+	case C_STOP:
+		return VSTOP;
+#endif /* VSTOP */
+#ifdef VWERASE
+	case C_WERASE:
+		return VWERASE;
+#endif /* VWERASE */
+#ifdef VSUSP
+	case C_SUSP:
+		return VSUSP;
+#endif /* VSUSP */
+#ifdef VDSUSP
+	case C_DSUSP:
+		return VDSUSP;
+#endif /* VDSUSP */
+#ifdef VREPRINT
+	case C_REPRINT:
+		return VREPRINT;
+#endif /* VREPRINT */
+#ifdef VDISCARD
+	case C_DISCARD:
+		return VDISCARD;
+#endif /* VDISCARD */
+#ifdef VLNEXT
+	case C_LNEXT:
+		return VLNEXT;
+#endif /* VLNEXT */
+#ifdef VSTATUS
+	case C_STATUS:
+		return VSTATUS;
+#endif /* VSTATUS */
+#ifdef VPAGE
+	case C_PAGE:
+		return VPAGE;
+#endif /* VPAGE */
+#ifdef VPGOFF
+	case C_PGOFF:
+		return VPGOFF;
+#endif /* VPGOFF */
+#ifdef VKILL2
+	case C_KILL2:
+		return VKILL2;
+#endif /* KILL2 */
+#ifdef VMIN
+	case C_MIN:
+		return VMIN;
+#endif /* VMIN */
+#ifdef VTIME
+	case C_TIME:
+		return VTIME;
+#endif /* VTIME */
+	default:
+		return -1;
+	}
+}
 
 /* tty__getchar():
  *	Get the tty characters
@@ -802,13 +932,22 @@
 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
 	el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
 
-	if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
+	if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
+	    tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
+		(void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
+		(void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
 		(void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
 		(void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
 	}
 	if (tty__cooked_mode(&el->el_tty.t_ts)) {
-		if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) &&
-		    (el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) {
+		if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
+			el->el_tty.t_ex.c_cflag =
+			    el->el_tty.t_ts.c_cflag;
+			el->el_tty.t_ex.c_cflag &=
+			    ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
+			el->el_tty.t_ex.c_cflag |=
+			    el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
+
 			el->el_tty.t_ed.c_cflag =
 			    el->el_tty.t_ts.c_cflag;
 			el->el_tty.t_ed.c_cflag &=
@@ -818,6 +957,13 @@
 		}
 		if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
 		    (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
+			el->el_tty.t_ex.c_lflag =
+			    el->el_tty.t_ts.c_lflag;
+			el->el_tty.t_ex.c_lflag &=
+			    ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
+			el->el_tty.t_ex.c_lflag |=
+			    el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
+
 			el->el_tty.t_ed.c_lflag =
 			    el->el_tty.t_ts.c_lflag;
 			el->el_tty.t_ed.c_lflag &=
@@ -827,6 +973,13 @@
 		}
 		if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
 		    (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
+			el->el_tty.t_ex.c_iflag =
+			    el->el_tty.t_ts.c_iflag;
+			el->el_tty.t_ex.c_iflag &=
+			    ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
+			el->el_tty.t_ex.c_iflag |=
+			    el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
+
 			el->el_tty.t_ed.c_iflag =
 			    el->el_tty.t_ts.c_iflag;
 			el->el_tty.t_ed.c_iflag &=
@@ -836,6 +989,13 @@
 		}
 		if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
 		    (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
+			el->el_tty.t_ex.c_oflag =
+			    el->el_tty.t_ts.c_oflag;
+			el->el_tty.t_ex.c_oflag &=
+			    ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
+			el->el_tty.t_ex.c_oflag |=
+			    el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
+
 			el->el_tty.t_ed.c_oflag =
 			    el->el_tty.t_ts.c_oflag;
 			el->el_tty.t_ed.c_oflag &=
@@ -884,13 +1044,10 @@
 					if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
 						el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
 				}
+				tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 			}
 		}
 	}
-
-	if (el->el_tty.t_mode == EX_IO)
-		el->el_tty.t_ex = el->el_tty.t_ts;
-
 	if (tty_setty(el, &el->el_tty.t_ed) == -1) {
 #ifdef DEBUG_TTY
 		(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
@@ -990,13 +1147,14 @@
  */
 protected int
 /*ARGSUSED*/
-tty_stty(EditLine *el, int argc, char **argv)
+tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
 {
 	const ttymodes_t *m;
-	char x, *d;
+	char x;
 	int aflag = 0;
-	char *s;
-	char *name;
+	const char *s, *d;
+	const char *name;
+	struct termios *tios = &el->el_tty.t_ex;
 	int z = EX_IO;
 
 	if (argv == NULL)
@@ -1011,14 +1169,17 @@
 			break;
 		case 'd':
 			argv++;
+			tios = &el->el_tty.t_ed;
 			z = ED_IO;
 			break;
 		case 'x':
 			argv++;
+			tios = &el->el_tty.t_ex;
 			z = EX_IO;
 			break;
 		case 'q':
 			argv++;
+			tios = &el->el_tty.t_ts;
 			z = QU_IO;
 			break;
 		default:
@@ -1068,6 +1229,7 @@
 		return (0);
 	}
 	while (argv && (s = *argv++)) {
+		char *p;
 		switch (*s) {
 		case '+':
 		case '-':
@@ -1078,14 +1240,27 @@
 			break;
 		}
 		d = s;
+		if ((p = strchr(s, '=')) != NULL)
+			*p++ = '\0';
 		for (m = ttymodes; m->m_name; m++)
-			if (strcmp(m->m_name, d) == 0)
+			if (strcmp(m->m_name, d) == 0 &&
+			    (p == NULL || m->m_type == MD_CHAR))
 				break;
 
 		if (!m->m_name) {
 			(void) fprintf(el->el_errfile,
 			    "%s: Invalid argument `%s'.\n", name, d);
 			return (-1);
+		}
+		if (p) {
+			int c = ffs((int)m->m_value);
+			int v = *p ? parse__escape((const char **const) &p) :
+			    el->el_tty.t_vdisable;
+			assert(c-- != 0);
+			c = tty__getcharindex(c);
+			assert(c != -1);
+			tios->c_cc[c] = v;
+			continue;
 		}
 		switch (x) {
 		case '+':
diff --exclude=CVS -ruN src.orig/lib/libedit/tty.h src/lib/libedit/tty.h
--- src.orig/lib/libedit/tty.h	Mon Oct  1 02:41:25 2001
+++ src/lib/libedit/tty.h	Wed Mar 30 21:22:15 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,8 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)tty.h	8.1 (Berkeley) 6/4/93
- *	$NetBSD: tty.h,v 1.7 1999/09/26 14:37:47 lukem Exp $
- * $FreeBSD: src/lib/libedit/tty.h,v 1.4 2001/10/01 08:41:25 obrien Exp $
+ * $FreeBSD$
  */
 
 /*
@@ -453,7 +450,7 @@
 #define	MD_NN	5
 
 typedef struct {
-	char	*t_name;
+	const char	*t_name;
 	u_int	 t_setmask;
 	u_int	 t_clrmask;
 } ttyperm_t[NN_IO][MD_NN];
@@ -462,7 +459,7 @@
 
 protected int	tty_init(EditLine *);
 protected void	tty_end(EditLine *);
-protected int	tty_stty(EditLine *, int, char**);
+protected int	tty_stty(EditLine *, int, const char **);
 protected int	tty_rawmode(EditLine *);
 protected int	tty_cookedmode(EditLine *);
 protected int	tty_quotemode(EditLine *);
diff --exclude=CVS -ruN src.orig/lib/libedit/vi.c src/lib/libedit/vi.c
--- src.orig/lib/libedit/vi.c	Wed Jan  1 11:48:44 2003
+++ src/lib/libedit/vi.c	Thu Mar 31 17:56:13 2005
@@ -1,3 +1,5 @@
+/*	$NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $	*/
+
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,11 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,20 +30,25 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	$NetBSD: vi.c,v 1.7 1999/07/02 15:21:28 simonb Exp $
  */
 
+#include "config.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
 #if !defined(lint) && !defined(SCCSID)
+#if 0
 static char sccsid[] = "@(#)vi.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $");
+#endif
 #endif /* not lint && not SCCSID */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libedit/vi.c,v 1.9 2003/01/01 18:48:44 schweikh Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * vi.c: Vi mode commands.
  */
-#include "sys.h"
 #include "el.h"
 
 private el_action_t	cv_action(EditLine *, int);
@@ -57,22 +60,18 @@
 private el_action_t
 cv_action(EditLine *el, int c)
 {
-	char *cp, *kp;
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
+	if (el->el_chared.c_vcmd.action != NOP) {
+		/* 'cc', 'dd' and (possibly) friends */
+		if (c != el->el_chared.c_vcmd.action)
+			return CC_ERROR;
+
+		if (!(c & YANK))
+			cv_undo(el);
+		cv_yank(el, el->el_line.buffer,
+			    el->el_line.lastchar - el->el_line.buffer);
 		el->el_chared.c_vcmd.action = NOP;
 		el->el_chared.c_vcmd.pos = 0;
-
-		el->el_chared.c_undo.isize = 0;
-		el->el_chared.c_undo.dsize = 0;
-		kp = el->el_chared.c_undo.buf;
-		for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
-			*kp++ = *cp;
-			el->el_chared.c_undo.dsize++;
-		}
-
-		el->el_chared.c_undo.action = INSERT;
-		el->el_chared.c_undo.ptr = el->el_line.buffer;
 		el->el_line.lastchar = el->el_line.buffer;
 		el->el_line.cursor = el->el_line.buffer;
 		if (c & INSERT)
@@ -83,25 +82,8 @@
 	el->el_chared.c_vcmd.pos = el->el_line.cursor;
 	el->el_chared.c_vcmd.action = c;
 	return (CC_ARGHACK);
-
-#ifdef notdef
-	/*
-         * I don't think that this is needed. But we keep it for now
-         */
-	else
-	if (el_chared.c_vcmd.action == NOP) {
-		el->el_chared.c_vcmd.pos = el->el_line.cursor;
-		el->el_chared.c_vcmd.action = c;
-		return (CC_ARGHACK);
-	} else {
-		el->el_chared.c_vcmd.action = 0;
-		el->el_chared.c_vcmd.pos = 0;
-		return (CC_ERROR);
-	}
-#endif
 }
 
-
 /* cv_paste():
  *	Paste previous deletion before or after the cursor
  */
@@ -109,23 +91,25 @@
 cv_paste(EditLine *el, int c)
 {
 	char *ptr;
-	c_undo_t *un = &el->el_chared.c_undo;
+	c_kill_t *k = &el->el_chared.c_kill;
+	int len = k->last - k->buf;
 
+	if (k->buf == NULL || len == 0)
+		return (CC_ERROR);
 #ifdef DEBUG_PASTE
-	(void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n",
-	    un->action, un->buf, un->isize, un->dsize);
+	(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf);
 #endif
-	if (un->isize == 0)
-		return (CC_ERROR);
+
+	cv_undo(el);
 
 	if (!c && el->el_line.cursor < el->el_line.lastchar)
 		el->el_line.cursor++;
 	ptr = el->el_line.cursor;
 
-	c_insert(el, (int) un->isize);
-	if (el->el_line.cursor + un->isize > el->el_line.lastchar)
+	c_insert(el, len);
+	if (el->el_line.cursor + len > el->el_line.lastchar)
 		return (CC_ERROR);
-	(void) memcpy(ptr, un->buf, un->isize);
+	(void) memcpy(ptr, k->buf, len +0u);
 	return (CC_REFRESH);
 }
 
@@ -136,7 +120,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_paste_next(EditLine *el, int c)
+vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_paste(el, 0));
@@ -149,31 +133,31 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_paste_prev(EditLine *el, int c)
+vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_paste(el, 1));
 }
 
 
-/* vi_prev_space_word():
+/* vi_prev_big_word():
  *	Vi move to the previous space delimited word
  *	[B]
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_space_word(EditLine *el, int c)
+vi_prev_big_word(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
 		return (CC_ERROR);
 
-	el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
 	    el->el_line.buffer,
 	    el->el_state.argument,
-	    c___isword);
+	    cv__isWord);
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
+	if (el->el_chared.c_vcmd.action != NOP) {
 		cv_delfini(el);
 		return (CC_REFRESH);
 	}
@@ -187,18 +171,18 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_word(EditLine *el, int c)
+vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
 		return (CC_ERROR);
 
-	el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
 	    el->el_line.buffer,
 	    el->el_state.argument,
 	    cv__isword);
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
+	if (el->el_chared.c_vcmd.action != NOP) {
 		cv_delfini(el);
 		return (CC_REFRESH);
 	}
@@ -206,25 +190,23 @@
 }
 
 
-/* vi_next_space_word():
+/* vi_next_big_word():
  *	Vi move to the next space delimited word
  *	[W]
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_space_word(EditLine *el, int c)
+vi_next_big_word(EditLine *el, int c)
 {
 
-	if (el->el_line.cursor == el->el_line.lastchar)
+	if (el->el_line.cursor >= el->el_line.lastchar - 1)
 		return (CC_ERROR);
 
 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
-	    el->el_line.lastchar,
-	    el->el_state.argument,
-	    c___isword);
+	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
 
 	if (el->el_map.type == MAP_VI)
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -238,19 +220,17 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_word(EditLine *el, int c)
+vi_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
-	if (el->el_line.cursor == el->el_line.lastchar)
+	if (el->el_line.cursor >= el->el_line.lastchar - 1)
 		return (CC_ERROR);
 
 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
-	    el->el_line.lastchar,
-	    el->el_state.argument,
-	    cv__isword);
+	    el->el_line.lastchar, el->el_state.argument, cv__isword);
 
 	if (el->el_map.type == MAP_VI)
-		if (el->el_chared.c_vcmd.action & DELETE) {
+		if (el->el_chared.c_vcmd.action != NOP) {
 			cv_delfini(el);
 			return (CC_REFRESH);
 		}
@@ -265,19 +245,27 @@
 protected el_action_t
 vi_change_case(EditLine *el, int c)
 {
+	int i;
 
-	if (el->el_line.cursor < el->el_line.lastchar) {
-		c = (unsigned char)*el->el_line.cursor;
+	if (el->el_line.cursor >= el->el_line.lastchar)
+		return (CC_ERROR);
+	cv_undo(el);
+	for (i = 0; i < el->el_state.argument; i++) {
+
+		c = *(unsigned char *)el->el_line.cursor;
 		if (isupper(c))
-			*el->el_line.cursor++ = tolower(c);
+			*el->el_line.cursor = tolower(c);
 		else if (islower(c))
-			*el->el_line.cursor++ = toupper(c);
-		else
-			el->el_line.cursor++;
+			*el->el_line.cursor = toupper(c);
+
+		if (++el->el_line.cursor >= el->el_line.lastchar) {
+			el->el_line.cursor--;
+			re_fastaddc(el);
+			break;
+		}
 		re_fastaddc(el);
-		return (CC_NORM);
 	}
-	return (CC_ERROR);
+	return CC_NORM;
 }
 
 
@@ -287,7 +275,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_change_meta(EditLine *el, int c)
+vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	/*
@@ -304,15 +292,11 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_insert_at_bol(EditLine *el, int c)
+vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.buffer;
-	el->el_chared.c_vcmd.ins = el->el_line.cursor;
-
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.action = DELETE;
-
+	cv_undo(el);
 	el->el_map.current = el->el_map.key;
 	return (CC_CURSOR);
 }
@@ -324,15 +308,15 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_replace_char(EditLine *el, int c)
+vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
+	if (el->el_line.cursor >= el->el_line.lastchar)
+		return CC_ERROR;
+
 	el->el_map.current = el->el_map.key;
 	el->el_state.inputmode = MODE_REPLACE_1;
-	el->el_chared.c_undo.action = CHANGE;
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.isize = 0;
-	el->el_chared.c_undo.dsize = 0;
+	cv_undo(el);
 	return (CC_ARGHACK);
 }
 
@@ -343,16 +327,13 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_replace_mode(EditLine *el, int c)
+vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
 	el->el_state.inputmode = MODE_REPLACE;
-	el->el_chared.c_undo.action = CHANGE;
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.isize = 0;
-	el->el_chared.c_undo.dsize = 0;
-	return (CC_ARGHACK);
+	cv_undo(el);
+	return (CC_NORM);
 }
 
 
@@ -362,7 +343,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_substitute_char(EditLine *el, int c)
+vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	c_delafter(el, el->el_state.argument);
@@ -377,9 +358,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_substitute_line(EditLine *el, int c)
+vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
 {
 
+	cv_undo(el);
+	cv_yank(el, el->el_line.buffer,
+		    el->el_line.lastchar - el->el_line.buffer);
 	(void) em_kill_line(el, 0);
 	el->el_map.current = el->el_map.key;
 	return (CC_REFRESH);
@@ -392,9 +376,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_change_to_eol(EditLine *el, int c)
+vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
 {
 
+	cv_undo(el);
+	cv_yank(el, el->el_line.cursor,
+		    el->el_line.lastchar - el->el_line.cursor);
 	(void) ed_kill_line(el, 0);
 	el->el_map.current = el->el_map.key;
 	return (CC_REFRESH);
@@ -407,15 +394,11 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_insert(EditLine *el, int c)
+vi_insert(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
-
-	el->el_chared.c_vcmd.ins = el->el_line.cursor;
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.action = DELETE;
-
+	cv_undo(el);
 	return (CC_NORM);
 }
 
@@ -426,9 +409,9 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_add(EditLine *el, int c)
+vi_add(EditLine *el, int c __attribute__((__unused__)))
 {
-	el_action_t ret;
+	int ret;
 
 	el->el_map.current = el->el_map.key;
 	if (el->el_line.cursor < el->el_line.lastchar) {
@@ -439,9 +422,7 @@
 	} else
 		ret = CC_NORM;
 
-	el->el_chared.c_vcmd.ins = el->el_line.cursor;
-	el->el_chared.c_undo.ptr = el->el_line.cursor;
-	el->el_chared.c_undo.action = DELETE;
+	cv_undo(el);
 
 	return (ret);
 }
@@ -453,16 +434,12 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_add_at_eol(EditLine *el, int c)
+vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
 	el->el_line.cursor = el->el_line.lastchar;
-
-	/* Mark where insertion begins */
-	el->el_chared.c_vcmd.ins = el->el_line.lastchar;
-	el->el_chared.c_undo.ptr = el->el_line.lastchar;
-	el->el_chared.c_undo.action = DELETE;
+	cv_undo(el);
 	return (CC_CURSOR);
 }
 
@@ -473,29 +450,29 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_delete_meta(EditLine *el, int c)
+vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_action(el, DELETE));
 }
 
 
-/* vi_end_word():
+/* vi_end_big_word():
  *	Vi move to the end of the current space delimited word
  *	[E]
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_end_word(EditLine *el, int c)
+vi_end_big_word(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar)
 		return (CC_ERROR);
 
 	el->el_line.cursor = cv__endword(el->el_line.cursor,
-	    el->el_line.lastchar, el->el_state.argument);
+	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
+	if (el->el_chared.c_vcmd.action != NOP) {
 		el->el_line.cursor++;
 		cv_delfini(el);
 		return (CC_REFRESH);
@@ -504,22 +481,22 @@
 }
 
 
-/* vi_to_end_word():
+/* vi_end_word():
  *	Vi move to the end of the current word
  *	[e]
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_end_word(EditLine *el, int c)
+vi_end_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar)
 		return (CC_ERROR);
 
 	el->el_line.cursor = cv__endword(el->el_line.cursor,
-	    el->el_line.lastchar, el->el_state.argument);
+	    el->el_line.lastchar, el->el_state.argument, cv__isword);
 
-	if (el->el_chared.c_vcmd.action & DELETE) {
+	if (el->el_chared.c_vcmd.action != NOP) {
 		el->el_line.cursor++;
 		cv_delfini(el);
 		return (CC_REFRESH);
@@ -534,144 +511,40 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_undo(EditLine *el, int c)
+vi_undo(EditLine *el, int c __attribute__((__unused__)))
 {
-	char *cp, *kp;
-	char temp;
-	int i, size;
-	c_undo_t *un = &el->el_chared.c_undo;
-
-#ifdef DEBUG_UNDO
-	(void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n",
-	    un->action, un->buf, un->isize, un->dsize);
-#endif
-	switch (un->action) {
-	case DELETE:
-		if (un->dsize == 0)
-			return (CC_NORM);
-
-		(void) memcpy(un->buf, un->ptr, un->dsize);
-		for (cp = un->ptr; cp <= el->el_line.lastchar; cp++)
-			*cp = cp[un->dsize];
-
-		el->el_line.lastchar -= un->dsize;
-		el->el_line.cursor = un->ptr;
-
-		un->action = INSERT;
-		un->isize = un->dsize;
-		un->dsize = 0;
-		break;
-
-	case DELETE | INSERT:
-		size = un->isize - un->dsize;
-		if (size > 0)
-			i = un->dsize;
-		else
-			i = un->isize;
-		cp = un->ptr;
-		kp = un->buf;
-		while (i-- > 0) {
-			temp = *kp;
-			*kp++ = *cp;
-			*cp++ = temp;
-		}
-		if (size > 0) {
-			el->el_line.cursor = cp;
-			c_insert(el, size);
-			while (size-- > 0 && cp < el->el_line.lastchar) {
-				temp = *kp;
-				*kp++ = *cp;
-				*cp++ = temp;
-			}
-		} else if (size < 0) {
-			size = -size;
-			for (; cp <= el->el_line.lastchar; cp++) {
-				*kp++ = *cp;
-				*cp = cp[size];
-			}
-			el->el_line.lastchar -= size;
-		}
-		el->el_line.cursor = un->ptr;
-		i = un->dsize;
-		un->dsize = un->isize;
-		un->isize = i;
-		break;
-
-	case INSERT:
-		if (un->isize == 0)
-			return (CC_NORM);
-
-		el->el_line.cursor = un->ptr;
-		c_insert(el, (int) un->isize);
-		(void) memcpy(un->ptr, un->buf, un->isize);
-		un->action = DELETE;
-		un->dsize = un->isize;
-		un->isize = 0;
-		break;
+	c_undo_t un = el->el_chared.c_undo;
 
-	case CHANGE:
-		if (un->isize == 0)
-			return (CC_NORM);
-
-		el->el_line.cursor = un->ptr;
-		size = (int) (el->el_line.cursor - el->el_line.lastchar);
-		if (size < un->isize)
-			size = un->isize;
-		cp = un->ptr;
-		kp = un->buf;
-		for (i = 0; i < size; i++) {
-			temp = *kp;
-			*kp++ = *cp;
-			*cp++ = temp;
-		}
-		un->dsize = 0;
-		break;
+	if (un.len == -1)
+		return CC_ERROR;
 
-	default:
-		return (CC_ERROR);
-	}
+	/* switch line buffer and undo buffer */
+	el->el_chared.c_undo.buf = el->el_line.buffer;
+	el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
+	el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer;
+	el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
+	el->el_line.buffer = un.buf;
+	el->el_line.cursor = un.buf + un.cursor;
+	el->el_line.lastchar = un.buf + un.len;
 
 	return (CC_REFRESH);
 }
 
 
-/* vi_undo_line():
- *	Vi undo all changes
- *	[U]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_undo_line(EditLine *el, int c)
-{
-
-	return hist_get(el);
-}
-
-
 /* vi_command_mode():
  *	Vi enter command mode (use alternative key bindings)
  *	[<ESC>]
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_command_mode(EditLine *el, int c)
+vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
 {
-	int size;
 
 	/* [Esc] cancels pending action */
-	el->el_chared.c_vcmd.ins = 0;
 	el->el_chared.c_vcmd.action = NOP;
 	el->el_chared.c_vcmd.pos = 0;
 
 	el->el_state.doingarg = 0;
-	size = el->el_chared.c_undo.ptr - el->el_line.cursor;
-	if (size < 0)
-		size = -size;
-	if (el->el_chared.c_undo.action == (INSERT | DELETE) ||
-	    el->el_chared.c_undo.action == DELETE)
-		el->el_chared.c_undo.dsize = size;
-	else
-		el->el_chared.c_undo.isize = size;
 
 	el->el_state.inputmode = MODE_INSERT;
 	el->el_map.current = el->el_map.alt;
@@ -691,42 +564,32 @@
 vi_zero(EditLine *el, int c)
 {
 
-	if (el->el_state.doingarg) {
-		if (el->el_state.argument > 1000000)
-			return (CC_ERROR);
-		el->el_state.argument =
-		    (el->el_state.argument * 10) + (c - '0');
-		return (CC_ARGHACK);
-	} else {
-		el->el_line.cursor = el->el_line.buffer;
-		if (el->el_chared.c_vcmd.action & DELETE) {
-			cv_delfini(el);
-			return (CC_REFRESH);
-		}
-		return (CC_CURSOR);
+	if (el->el_state.doingarg)
+		return ed_argument_digit(el, c);
+
+	el->el_line.cursor = el->el_line.buffer;
+	if (el->el_chared.c_vcmd.action != NOP) {
+		cv_delfini(el);
+		return (CC_REFRESH);
 	}
+	return (CC_CURSOR);
 }
 
 
 /* vi_delete_prev_char():
  * 	Vi move to previous character (backspace)
- *	[^H]
+ *	[^H] in insert mode only
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_delete_prev_char(EditLine *el, int c)
+vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
-	if (el->el_chared.c_vcmd.ins == 0)
-		return (CC_ERROR);
-
-	if (el->el_chared.c_vcmd.ins >
-	    el->el_line.cursor - el->el_state.argument)
+	if (el->el_line.cursor <= el->el_line.buffer)
 		return (CC_ERROR);
 
-	c_delbefore(el, el->el_state.argument);
-	el->el_line.cursor -= el->el_state.argument;
-
+	c_delbefore1(el);
+	el->el_line.cursor--;
 	return (CC_REFRESH);
 }
 
@@ -737,23 +600,35 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_list_or_eof(EditLine *el, int c)
+vi_list_or_eof(EditLine *el, int c __attribute__((__unused__)))
 {
 
-#ifdef notyet
-	if (el->el_line.cursor == el->el_line.lastchar &&
-	    el->el_line.cursor == el->el_line.buffer) {
-#endif
-		term_overwrite(el, STReof, 4);	/* then do an EOF */
-		term__flush();
-		return (CC_EOF);
-#ifdef notyet
+	if (el->el_line.cursor == el->el_line.lastchar) {
+		if (el->el_line.cursor == el->el_line.buffer) {
+			term_overwrite(el, STReof, 4);	/* then do a EOF */
+			term__flush();
+			return (CC_EOF);
+		} else {
+			/*
+			 * Here we could list completions, but it is an
+			 * error right now
+			 */
+			term_beep(el);
+			return (CC_ERROR);
+		}
 	} else {
+#ifdef notyet
 		re_goto_bottom(el);
 		*el->el_line.lastchar = '\0';	/* just in case */
 		return (CC_LIST_CHOICES);
-	}
+#else
+		/*
+		 * Just complain for now.
+		 */
+		term_beep(el);
+		return (CC_ERROR);
 #endif
+	}
 }
 
 
@@ -763,7 +638,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_kill_line_prev(EditLine *el, int c)
+vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -784,7 +659,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_search_prev(EditLine *el, int c)
+vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_search(el, ED_SEARCH_PREV_HISTORY));
@@ -797,7 +672,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_search_next(EditLine *el, int c)
+vi_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
@@ -810,7 +685,7 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_search_next(EditLine *el, int c)
+vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_search.patlen == 0)
@@ -826,7 +701,7 @@
  */
 /*ARGSUSED*/
 protected el_action_t
-vi_repeat_search_prev(EditLine *el, int c)
+vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_search.patlen == 0)
@@ -844,18 +719,9 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_char(EditLine *el, int c)
+vi_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
-	char ch;
-
-	if (el_getc(el, &ch) != 1)
-		return (ed_end_of_file(el, 0));
-
-	el->el_search.chadir = CHAR_FWD;
-	el->el_search.chacha = ch;
-
-	return (cv_csearch_fwd(el, ch, el->el_state.argument, 0));
-
+	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
 }
 
 
@@ -865,17 +731,9 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_char(EditLine *el, int c)
+vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
-	char ch;
-
-	if (el_getc(el, &ch) != 1)
-		return (ed_end_of_file(el, 0));
-
-	el->el_search.chadir = CHAR_BACK;
-	el->el_search.chacha = ch;
-
-	return (cv_csearch_back(el, ch, el->el_state.argument, 0));
+	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
 }
 
 
@@ -885,15 +743,9 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_next_char(EditLine *el, int c)
+vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
-	char ch;
-
-	if (el_getc(el, &ch) != 1)
-		return (ed_end_of_file(el, 0));
-
-	return (cv_csearch_fwd(el, ch, el->el_state.argument, 1));
-
+	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
 }
 
 
@@ -903,14 +755,9 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_prev_char(EditLine *el, int c)
+vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
-	char ch;
-
-	if (el_getc(el, &ch) != 1)
-		return (ed_end_of_file(el, 0));
-
-	return (cv_csearch_back(el, ch, el->el_state.argument, 1));
+	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
 }
 
 
@@ -920,17 +767,11 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_next_char(EditLine *el, int c)
+vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
-	if (el->el_search.chacha == 0)
-		return (CC_ERROR);
-
-	return (el->el_search.chadir == CHAR_FWD
-	    ? cv_csearch_fwd(el, el->el_search.chacha,
-		el->el_state.argument, 0)
-	    : cv_csearch_back(el, el->el_search.chacha,
-		el->el_state.argument, 0));
+	return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
+		el->el_state.argument, el->el_search.chatflg);
 }
 
 
@@ -940,13 +781,345 @@
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_prev_char(EditLine *el, int c)
+vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
+	el_action_t r;
+	int dir = el->el_search.chadir;
 
-	if (el->el_search.chacha == 0)
-		return (CC_ERROR);
+	r = cv_csearch(el, -dir, el->el_search.chacha,
+		el->el_state.argument, el->el_search.chatflg);
+	el->el_search.chadir = dir;
+	return r;
+}
+
+
+/* vi_match():
+ *	Vi go to matching () {} or []
+ *	[%]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_match(EditLine *el, int c)
+{
+	const char match_chars[] = "()[]{}";
+	char *cp;
+	int delta, i, count;
+	char o_ch, c_ch;
+
+	*el->el_line.lastchar = '\0';		/* just in case */
+
+	i = strcspn(el->el_line.cursor, match_chars);
+	o_ch = el->el_line.cursor[i];
+	if (o_ch == 0)
+		return CC_ERROR;
+	delta = strchr(match_chars, o_ch) - match_chars;
+	c_ch = match_chars[delta ^ 1];
+	count = 1;
+	delta = 1 - (delta & 1) * 2;
+
+	for (cp = &el->el_line.cursor[i]; count; ) {
+		cp += delta;
+		if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
+			return CC_ERROR;
+		if (*cp == o_ch)
+			count++;
+		else if (*cp == c_ch)
+			count--;
+	}
+
+	el->el_line.cursor = cp;
+
+	if (el->el_chared.c_vcmd.action != NOP) {
+		/* NB posix says char under cursor should NOT be deleted
+		   for -ve delta - this is different to netbsd vi. */
+		if (delta > 0)
+			el->el_line.cursor++;
+		cv_delfini(el);
+		return (CC_REFRESH);
+	}
+	return (CC_CURSOR);
+}
+
+/* vi_undo_line():
+ *	Vi undo all changes to line
+ *	[U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_undo_line(EditLine *el, int c)
+{
+
+	cv_undo(el);
+	return hist_get(el);
+}
+
+/* vi_to_column():
+ *	Vi go to specified column
+ *	[|]
+ * NB netbsd vi goes to screen column 'n', posix says nth character
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_to_column(EditLine *el, int c)
+{
+
+	el->el_line.cursor = el->el_line.buffer;
+	el->el_state.argument--;
+	return ed_next_char(el, 0);
+}
+
+/* vi_yank_end():
+ *	Vi yank to end of line
+ *	[Y]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_yank_end(EditLine *el, int c)
+{
+
+	cv_yank(el, el->el_line.cursor,
+		el->el_line.lastchar - el->el_line.cursor);
+	return CC_REFRESH;
+}
+
+/* vi_yank():
+ *	Vi yank
+ *	[y]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_yank(EditLine *el, int c)
+{
+
+	return cv_action(el, YANK);
+}
+
+/* vi_comment_out():
+ *	Vi comment out current command
+ *	[c]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_comment_out(EditLine *el, int c)
+{
+
+	el->el_line.cursor = el->el_line.buffer;
+	c_insert(el, 1);
+	*el->el_line.cursor = '#';
+	re_refresh(el);
+	return ed_newline(el, 0);
+}
+
+/* vi_alias():
+ *	Vi include shell alias
+ *	[@]
+ * NB: posix impiles that we should enter insert mode, however
+ * this is against historical precedent...
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_alias(EditLine *el, int c)
+{
+#ifdef __weak_extern
+	char alias_name[3];
+	char *alias_text;
+	extern char *get_alias_text(const char *);
+	__weak_extern(get_alias_text);
+
+	if (get_alias_text == 0) {
+		return CC_ERROR;
+	}
+
+	alias_name[0] = '_';
+	alias_name[2] = 0;
+	if (el_getc(el, &alias_name[1]) != 1)
+		return CC_ERROR;
+
+	alias_text = get_alias_text(alias_name);
+	if (alias_text != NULL)
+		el_push(el, alias_text);
+	return CC_NORM;
+#else
+	return CC_ERROR;
+#endif
+}
+
+/* vi_to_history_line():
+ *	Vi go to specified history file line.
+ *	[G]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_to_history_line(EditLine *el, int c)
+{
+	int sv_event_no = el->el_history.eventno;
+	el_action_t rval;
+
+
+	if (el->el_history.eventno == 0) {
+		 (void) strncpy(el->el_history.buf, el->el_line.buffer,
+		     EL_BUFSIZ);
+		 el->el_history.last = el->el_history.buf +
+			 (el->el_line.lastchar - el->el_line.buffer);
+	}
+
+	/* Lack of a 'count' means oldest, not 1 */
+	if (!el->el_state.doingarg) {
+		el->el_history.eventno = 0x7fffffff;
+		hist_get(el);
+	} else {
+		/* This is brain dead, all the rest of this code counts
+		 * upwards going into the past.  Here we need count in the
+		 * other direction (to match the output of fc -l).
+		 * I could change the world, but this seems to suffice.
+		 */
+		el->el_history.eventno = 1;
+		if (hist_get(el) == CC_ERROR)
+			return CC_ERROR;
+		el->el_history.eventno = 1 + el->el_history.ev.num 
+					- el->el_state.argument;
+		if (el->el_history.eventno < 0) {
+			el->el_history.eventno = sv_event_no;
+			return CC_ERROR;
+		}
+	}
+	rval = hist_get(el);
+	if (rval == CC_ERROR)
+		el->el_history.eventno = sv_event_no;
+	return rval;
+}
+
+/* vi_histedit():
+ *	Vi edit history line with vi
+ *	[v]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_histedit(EditLine *el, int c)
+{
+	int fd;
+	pid_t pid;
+	int st;
+	char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
+	char *cp;
+
+	if (el->el_state.doingarg) {
+		if (vi_to_history_line(el, 0) == CC_ERROR)
+			return CC_ERROR;
+	}
+
+	fd = mkstemp(tempfile);
+	if (fd < 0)
+		return CC_ERROR;
+	cp = el->el_line.buffer;
+	write(fd, cp, el->el_line.lastchar - cp +0u);
+	write(fd, "\n", 1);
+	pid = fork();
+	switch (pid) {
+	case -1:
+		close(fd);
+		unlink(tempfile);
+		return CC_ERROR;
+	case 0:
+		close(fd);
+		execlp("vi", "vi", tempfile, 0);
+		exit(0);
+		/*NOTREACHED*/
+	default:
+		while (waitpid(pid, &st, 0) != pid)
+			continue;
+		lseek(fd, 0ll, SEEK_SET);
+		st = read(fd, cp, el->el_line.limit - cp +0u);
+		if (st > 0 && cp[st - 1] == '\n')
+			st--;
+		el->el_line.cursor = cp;
+		el->el_line.lastchar = cp + st;
+		break;
+	}
+
+	close(fd);
+	unlink(tempfile);
+	/* return CC_REFRESH; */
+	return ed_newline(el, 0);
+}
+
+/* vi_history_word():
+ *	Vi append word from previous input line
+ *	[_]
+ * Who knows where this one came from!
+ * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_history_word(EditLine *el, int c)
+{
+	const char *wp = HIST_FIRST(el);
+	const char *wep, *wsp;
+	int len;
+	char *cp;
+	const char *lim;
+
+	if (wp == NULL)
+		return CC_ERROR;
+
+	wep = wsp = 0;
+	do {
+		while (isspace((unsigned char)*wp))
+			wp++;
+		if (*wp == 0)
+			break;
+		wsp = wp;
+		while (*wp && !isspace((unsigned char)*wp))
+			wp++;
+		wep = wp;
+	} while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0);
+
+	if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
+		return CC_ERROR;
+
+	cv_undo(el);
+	len = wep - wsp;
+	if (el->el_line.cursor < el->el_line.lastchar)
+		el->el_line.cursor++;
+	c_insert(el, len + 1);
+	cp = el->el_line.cursor;
+	lim = el->el_line.limit;
+	if (cp < lim)
+		*cp++ = ' ';
+	while (wsp < wep && cp < lim)
+		*cp++ = *wsp++;
+	el->el_line.cursor = cp;
+
+	el->el_map.current = el->el_map.key;
+	return CC_REFRESH;
+}
+
+/* vi_redo():
+ *	Vi redo last non-motion command
+ *	[.]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_redo(EditLine *el, int c)
+{
+	c_redo_t *r = &el->el_chared.c_redo;
+
+	if (!el->el_state.doingarg && r->count) {
+		el->el_state.doingarg = 1;
+		el->el_state.argument = r->count;
+	}
+
+	el->el_chared.c_vcmd.pos = el->el_line.cursor;
+	el->el_chared.c_vcmd.action = r->action;
+	if (r->pos != r->buf) {
+		if (r->pos + 1 > r->lim)
+			/* sanity */
+			r->pos = r->lim - 1;
+		r->pos[0] = 0;
+		el_push(el, r->buf);
+	}
 
-	return el->el_search.chadir == CHAR_BACK ?
-	    cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
-	    cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
+	el->el_state.thiscmd = r->cmd;
+	el->el_state.thisch = r->ch;
+	return  (*el->el_map.func[r->cmd])(el, r->ch);
 }
--- libedit-sync-patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200504010233.j312X5hL083878>