git: 8df2a400e8e1 - stable/13 - libedit: import version of 2022-04-11

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Wed, 12 Oct 2022 08:49:17 UTC
The branch stable/13 has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=8df2a400e8e19da73804217ebb5064816fc2971a

commit 8df2a400e8e19da73804217ebb5064816fc2971a
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2022-04-14 14:46:47 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2022-10-12 08:48:19 +0000

    libedit: import version of 2022-04-11
    
    It includes improvements in the libreadline compatibility and a change
    from pstef@ which fixes filename autocompletion for strings like a\)b
    
    (cherry picked from commit 7f39937557052c004d7ebf55dd973108323756f3)
---
 contrib/libedit/chared.c            |  67 ++++++++++++++++++++-
 contrib/libedit/chartype.h          |   3 +-
 contrib/libedit/eln.c               |  10 +++-
 contrib/libedit/filecomplete.c      |  43 +++++++-------
 contrib/libedit/filecomplete.h      |   4 +-
 contrib/libedit/histedit.h          |   6 +-
 contrib/libedit/readline.c          | 112 +++++++++++++++++++++++++++++++++---
 contrib/libedit/readline/readline.h |  26 +++++++--
 8 files changed, 229 insertions(+), 42 deletions(-)

diff --git a/contrib/libedit/chared.c b/contrib/libedit/chared.c
index a96322aa6883..ff5545bbe168 100644
--- a/contrib/libedit/chared.c
+++ b/contrib/libedit/chared.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $	*/
+/*	$NetBSD: chared.c,v 1.62 2022/02/08 21:13:22 rillig Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)chared.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $");
+__RCSID("$NetBSD: chared.c,v 1.62 2022/02/08 21:13:22 rillig Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -624,6 +624,69 @@ el_deletestr(EditLine *el, int n)
 		el->el_line.cursor = el->el_line.buffer;
 }
 
+/* el_deletestr1():
+ *	Delete characters between start and end
+ */
+int
+el_deletestr1(EditLine *el, int start, int end)
+{
+	size_t line_length, len;
+	wchar_t *p1, *p2;
+
+	if (end <= start)
+		return 0;
+
+	line_length = (size_t)(el->el_line.lastchar - el->el_line.buffer);
+
+	if (start >= (int)line_length || end >= (int)line_length)
+		return 0;
+
+	len = (size_t)(end - start);
+	if (len > line_length - (size_t)end)
+		len = line_length - (size_t)end;
+
+	p1 = el->el_line.buffer + start;
+	p2 = el->el_line.buffer + end;
+	for (size_t i = 0; i < len; i++) {
+		*p1++ = *p2++;
+		el->el_line.lastchar--;
+	}
+
+	if (el->el_line.cursor < el->el_line.buffer)
+		el->el_line.cursor = el->el_line.buffer;
+
+	return end - start;
+}
+
+/* el_wreplacestr():
+ *	Replace the contents of the line with the provided string
+ */
+int
+el_wreplacestr(EditLine *el, const wchar_t *s)
+{
+	size_t len;
+	wchar_t * p;
+
+	if (s == NULL || (len = wcslen(s)) == 0)
+		return -1;
+
+	if (el->el_line.buffer + len >= el->el_line.limit) {
+		if (!ch_enlargebufs(el, len))
+			return -1;
+	}
+
+	p = el->el_line.buffer;
+	for (size_t i = 0; i < len; i++)
+		*p++ = *s++;
+
+	el->el_line.buffer[len] = '\0';
+	el->el_line.lastchar = el->el_line.buffer + len;
+	if (el->el_line.cursor > el->el_line.lastchar)
+		el->el_line.cursor = el->el_line.lastchar;
+
+	return 0;
+}
+
 /* el_cursor():
  *	Move the cursor to the left or the right of the current position
  */
diff --git a/contrib/libedit/chartype.h b/contrib/libedit/chartype.h
index bfa3d54ec36c..bcdb293a12f4 100644
--- a/contrib/libedit/chartype.h
+++ b/contrib/libedit/chartype.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: chartype.h,v 1.36 2019/09/15 21:09:11 christos Exp $	*/
+/*	$NetBSD: chartype.h,v 1.37 2022/04/11 19:37:20 tnn Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -35,6 +35,7 @@
  * been around since 2001... */
 #if	!defined(__NetBSD__) && \
 	!defined(__sun) && \
+	!defined(__osf__) && \
 	!(defined(__APPLE__) && defined(__MACH__)) && \
 	!defined(__OpenBSD__) && \
 	!defined(__FreeBSD__) && \
diff --git a/contrib/libedit/eln.c b/contrib/libedit/eln.c
index f432a2187c0d..563ec2a672a9 100644
--- a/contrib/libedit/eln.c
+++ b/contrib/libedit/eln.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: eln.c,v 1.36 2021/08/15 10:08:41 christos Exp $	*/
+/*	$NetBSD: eln.c,v 1.37 2022/01/11 18:30:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: eln.c,v 1.36 2021/08/15 10:08:41 christos Exp $");
+__RCSID("$NetBSD: eln.c,v 1.37 2022/01/11 18:30:15 christos Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <errno.h>
@@ -386,3 +386,9 @@ el_insertstr(EditLine *el, const char *str)
 {
 	return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
 }
+
+int
+el_replacestr(EditLine *el, const char *str)
+{
+	return el_wreplacestr(el, ct_decode_string(str, &el->el_lgcyconv));
+}
diff --git a/contrib/libedit/filecomplete.c b/contrib/libedit/filecomplete.c
index 6dc7cff1d055..844c3efa95dd 100644
--- a/contrib/libedit/filecomplete.c
+++ b/contrib/libedit/filecomplete.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecomplete.c,v 1.68 2021/05/05 14:49:59 christos Exp $	*/
+/*	$NetBSD: filecomplete.c,v 1.70 2022/03/12 15:29:17 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: filecomplete.c,v 1.68 2021/05/05 14:49:59 christos Exp $");
+__RCSID("$NetBSD: filecomplete.c,v 1.70 2022/03/12 15:29:17 christos Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <sys/types.h>
@@ -69,20 +69,21 @@ fn_tilde_expand(const char *txt)
 	char pwbuf[1024];
 #endif
 	struct passwd *pass;
+	const char *pos;
 	char *temp;
 	size_t len = 0;
 
 	if (txt[0] != '~')
 		return strdup(txt);
 
-	temp = strchr(txt + 1, '/');
-	if (temp == NULL) {
+	pos = strchr(txt + 1, '/');
+	if (pos == NULL) {
 		temp = strdup(txt + 1);
 		if (temp == NULL)
 			return NULL;
 	} else {
 		/* text until string after slash */
-		len = (size_t)(temp - txt + 1);
+		len = (size_t)(pos - txt + 1);
 		temp = el_calloc(len, sizeof(*temp));
 		if (temp == NULL)
 			return NULL;
@@ -126,7 +127,7 @@ fn_tilde_expand(const char *txt)
 }
 
 static int
-needs_escaping(char c)
+needs_escaping(wchar_t c)
 {
 	switch (c) {
 	case '\'':
@@ -212,9 +213,10 @@ escape_filename(EditLine * el, const char *filename, int single_match,
 	while (temp != el->el_line.cursor) {
 		/*
 		 * If we see a single quote but have not seen a double quote
-		 * so far set/unset s_quote
+		 * so far set/unset s_quote, unless it is already quoted
 		 */
-		if (temp[0] == '\'' && !d_quoted)
+		if (temp[0] == '\'' && !d_quoted &&
+		    (temp == el->el_line.buffer || temp[-1] != '\\'))
 			s_quoted = !s_quoted;
 		/*
 		 * vice versa to the above condition
@@ -327,14 +329,15 @@ fn_filename_completion_function(const char *text, int state)
 	static size_t filename_len = 0;
 	struct dirent *entry;
 	char *temp;
+	const char *pos;
 	size_t len;
 
 	if (state == 0 || dir == NULL) {
-		temp = strrchr(text, '/');
-		if (temp) {
+		pos = strrchr(text, '/');
+		if (pos) {
 			char *nptr;
-			temp++;
-			nptr = el_realloc(filename, (strlen(temp) + 1) *
+			pos++;
+			nptr = el_realloc(filename, (strlen(pos) + 1) *
 			    sizeof(*nptr));
 			if (nptr == NULL) {
 				el_free(filename);
@@ -342,8 +345,8 @@ fn_filename_completion_function(const char *text, int state)
 				return NULL;
 			}
 			filename = nptr;
-			(void)strcpy(filename, temp);
-			len = (size_t)(temp - text);	/* including last slash */
+			(void)strcpy(filename, pos);
+			len = (size_t)(pos - text);	/* including last slash */
 
 			nptr = el_realloc(dirname, (len + 1) *
 			    sizeof(*nptr));
@@ -609,13 +612,13 @@ find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
 	for (;;) {
 		if (ctemp <= buffer)
 			break;
-		if (wcschr(word_break, ctemp[-1])) {
-			if (ctemp - buffer >= 2 && ctemp[-2] == '\\') {
-				ctemp -= 2;
-				continue;
-			}
-			break;
+		if (ctemp - buffer >= 2 && ctemp[-2] == '\\' &&
+		    needs_escaping(ctemp[-1])) {
+			ctemp -= 2;
+			continue;
 		}
+		if (wcschr(word_break, ctemp[-1]))
+			break;
 		if (special_prefixes && wcschr(special_prefixes, ctemp[-1]))
 			break;
 		ctemp--;
diff --git a/contrib/libedit/filecomplete.h b/contrib/libedit/filecomplete.h
index 60ea4894414b..796ae7ab3276 100644
--- a/contrib/libedit/filecomplete.h
+++ b/contrib/libedit/filecomplete.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecomplete.h,v 1.13 2021/03/28 13:38:10 christos Exp $	*/
+/*	$NetBSD: filecomplete.h,v 1.14 2021/09/26 13:45:54 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@ int fn_complete2(EditLine *,
     char **(*)(const char *, int, int),
     const wchar_t *, const wchar_t *, const char *(*)(const char *), size_t,
     int *, int *, int *, int *, unsigned int);
-#define FN_QUOTE_MATCH 1		/* Quote the returned match */
+#define FN_QUOTE_MATCH 1U		/* Quote the returned match */
 
 void fn_display_match_list(EditLine *, char **, size_t, size_t,
 	const char *(*)(const char *));
diff --git a/contrib/libedit/histedit.h b/contrib/libedit/histedit.h
index 511750e0137e..507c71a6ceb1 100644
--- a/contrib/libedit/histedit.h
+++ b/contrib/libedit/histedit.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: histedit.h,v 1.58 2021/08/15 10:08:41 christos Exp $	*/
+/*	$NetBSD: histedit.h,v 1.61 2022/02/08 21:13:22 rillig Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -180,7 +180,8 @@ void		 el_resize(EditLine *);
 const LineInfo	*el_line(EditLine *);
 int		 el_insertstr(EditLine *, const char *);
 void		 el_deletestr(EditLine *, int);
-
+int		 el_replacestr(EditLine *, const char *);
+int		 el_deletestr1(EditLine *, int, int);
 
 /*
  * ==== History ====
@@ -279,6 +280,7 @@ int		 el_cursor(EditLine *, int);
 const LineInfoW	*el_wline(EditLine *);
 int		 el_winsertstr(EditLine *, const wchar_t *);
 #define          el_wdeletestr  el_deletestr
+int		 el_wreplacestr(EditLine *, const wchar_t *);
 
 /*
  * ==== History ====
diff --git a/contrib/libedit/readline.c b/contrib/libedit/readline.c
index c12eb7481bf4..7d7f1ec3b9fa 100644
--- a/contrib/libedit/readline.c
+++ b/contrib/libedit/readline.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: readline.c,v 1.168 2021/09/10 18:51:36 rillig Exp $	*/
+/*	$NetBSD: readline.c,v 1.174 2022/04/08 20:11:31 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: readline.c,v 1.168 2021/09/10 18:51:36 rillig Exp $");
+__RCSID("$NetBSD: readline.c,v 1.174 2022/04/08 20:11:31 christos Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <sys/types.h>
@@ -43,6 +43,7 @@ __RCSID("$NetBSD: readline.c,v 1.168 2021/09/10 18:51:36 rillig Exp $");
 #include <limits.h>
 #include <pwd.h>
 #include <setjmp.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -112,8 +113,8 @@ const char *rl_basic_quote_characters = "\"'";
 rl_compentry_func_t *rl_completion_entry_function = NULL;
 char *(*rl_completion_word_break_hook)(void) = NULL;
 rl_completion_func_t *rl_attempted_completion_function = NULL;
-Function *rl_pre_input_hook = NULL;
-Function *rl_startup1_hook = NULL;
+rl_hook_func_t *rl_pre_input_hook = NULL;
+rl_hook_func_t *rl_startup1_hook = NULL;
 int (*rl_getc_function)(FILE *) = NULL;
 char *rl_terminal_name = NULL;
 int rl_already_prompted = 0;
@@ -122,12 +123,12 @@ int rl_ignore_completion_duplicates = 0;
 int readline_echoing_p = 1;
 int _rl_print_completions_horizontally = 0;
 VFunction *rl_redisplay_function = NULL;
-Function *rl_startup_hook = NULL;
+rl_hook_func_t *rl_startup_hook = NULL;
 VFunction *rl_completion_display_matches_hook = NULL;
 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
-unsigned long rl_readline_state;
+unsigned long rl_readline_state = RL_STATE_NONE;
 int _rl_complete_mark_directories;
 rl_icppfunc_t *rl_directory_completion_hook;
 int rl_completion_suppress_append;
@@ -136,11 +137,13 @@ int _rl_completion_prefix_display_length;
 int _rl_echoing_p;
 int history_max_entries;
 char *rl_display_prompt;
+int rl_erase_empty_line;
 
 /*
  * The current prompt string.
  */
 char *rl_prompt = NULL;
+char *rl_prompt_saved = NULL;
 /*
  * This is set to character indicating type of completion being done by
  * rl_complete_internal(); this is available for application completion
@@ -278,6 +281,21 @@ rl_set_prompt(const char *prompt)
 	return 0;
 }
 
+void
+rl_save_prompt(void)
+{
+	rl_prompt_saved = strdup(rl_prompt);
+}
+
+void
+rl_restore_prompt(void)
+{
+	if (!rl_prompt_saved)
+		return;
+	rl_prompt = rl_prompt_saved;
+	rl_prompt_saved = NULL;
+}
+
 /*
  * initialize rl compat stuff
  */
@@ -293,6 +311,8 @@ rl_initialize(void)
 	if (h != NULL)
 		history_end(h);
 
+	RL_UNSETSTATE(RL_STATE_DONE);
+
 	if (!rl_instream)
 		rl_instream = stdin;
 	if (!rl_outstream)
@@ -425,7 +445,7 @@ readline(const char *p)
 	if (e == NULL || h == NULL)
 		rl_initialize();
 	if (rl_startup_hook) {
-		(*rl_startup_hook)(NULL, 0);
+		(*rl_startup_hook)();
 	}
 	tty_init(e);
 
@@ -440,7 +460,7 @@ readline(const char *p)
 		goto out;
 
 	if (rl_pre_input_hook)
-		(*rl_pre_input_hook)(NULL, 0);
+		(*rl_pre_input_hook)();
 
 	if (rl_event_hook && !(e->el_flags & NO_TTY)) {
 		el_set(e, EL_GETCFN, _rl_event_read_char);
@@ -2127,10 +2147,12 @@ rl_callback_read_char(void)
 		if (done == 2) {
 			if ((wbuf = strdup(buf)) != NULL)
 				wbuf[count] = '\0';
+			RL_SETSTATE(RL_STATE_DONE);
 		} else
 			wbuf = NULL;
 		(*(void (*)(const char *))rl_linefunc)(wbuf);
 	}
+	_rl_update_pos();
 }
 
 void
@@ -2158,6 +2180,7 @@ rl_redisplay(void)
 	a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
 	a[1] = '\0';
 	el_push(e, a);
+	rl_forced_update_display();
 }
 
 int
@@ -2281,6 +2304,56 @@ _rl_update_pos(void)
 	rl_line_buffer[rl_end] = '\0';
 }
 
+char *
+rl_copy_text(int from, int to)
+{
+	const LineInfo *li;
+	size_t len;
+	char * out;
+
+	if (h == NULL || e == NULL)
+		rl_initialize();
+
+	li = el_line(e);
+
+	if (from > to)
+		return NULL;
+
+	if (li->buffer + from > li->lastchar)
+		from = (int)(li->lastchar - li->buffer);
+
+	if (li->buffer + to > li->lastchar)
+		to = (int)(li->lastchar - li->buffer);
+
+	len = (size_t)(to - from);
+	out = el_malloc((size_t)len + 1);
+	(void)strlcpy(out, li->buffer + from , len);
+
+	return out;
+}
+
+void
+rl_replace_line(const char * text, int clear_undo __attribute__((__unused__)))
+{
+	if (!text || *text == 0)
+		return;
+
+	if (h == NULL || e == NULL)
+		rl_initialize();
+
+	el_replacestr(e, text);
+}
+
+int
+rl_delete_text(int start, int end)
+{
+
+	if (h == NULL || e == NULL)
+		rl_initialize();
+
+	return el_deletestr1(e, start, end);
+}
+
 void
 rl_get_screen_size(int *rows, int *cols)
 {
@@ -2290,6 +2363,21 @@ rl_get_screen_size(int *rows, int *cols)
 		el_get(e, EL_GETTC, "co", cols);
 }
 
+#define MAX_MESSAGE 160
+void
+rl_message(const char *format, ...)
+{
+	char msg[MAX_MESSAGE];
+	va_list args;
+
+	va_start(args, format);
+	vsnprintf(msg, sizeof(msg), format, args);
+	va_end(args);
+
+	rl_set_prompt(msg);
+	rl_forced_update_display();
+}
+
 void
 rl_set_screen_size(int rows, int cols)
 {
@@ -2437,6 +2525,14 @@ rl_bind_key_in_map(int key __attribute__((__unused__)),
 	return 0;
 }
 
+int
+rl_set_key(const char *keyseq  __attribute__((__unused__)),
+	rl_command_func_t *function __attribute__((__unused__)),
+	Keymap k __attribute__((__unused__)))
+{
+	return 0;
+}
+
 /* unsupported, but needed by python */
 void
 rl_cleanup_after_signal(void)
diff --git a/contrib/libedit/readline/readline.h b/contrib/libedit/readline/readline.h
index e9f941aeb249..2bd0b7e80ab6 100644
--- a/contrib/libedit/readline/readline.h
+++ b/contrib/libedit/readline/readline.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: readline.h,v 1.47 2021/08/21 12:34:59 christos Exp $	*/
+/*	$NetBSD: readline.h,v 1.53 2022/02/19 17:45:02 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -94,6 +94,13 @@ typedef KEYMAP_ENTRY *Keymap;
 #define RL_PROMPT_START_IGNORE	'\1'
 #define RL_PROMPT_END_IGNORE	'\2'
 
+#define RL_STATE_NONE		0x000000
+#define RL_STATE_DONE		0x000001
+
+#define RL_SETSTATE(x)		(rl_readline_state |= ((unsigned long) x))
+#define RL_UNSETSTATE(x)	(rl_readline_state &= ~((unsigned long) x))
+#define RL_ISSTATE(x)		(rl_readline_state & ((unsigned long) x))
+
 /* global variables used by readline enabled applications */
 #ifdef __cplusplus
 extern "C" {
@@ -120,8 +127,8 @@ extern int		rl_completion_query_items;
 extern const char	*rl_special_prefixes;
 extern int		rl_completion_append_character;
 extern int		rl_inhibit_completion;
-extern Function		*rl_pre_input_hook;
-extern Function		*rl_startup_hook;
+extern rl_hook_func_t		*rl_pre_input_hook;
+extern rl_hook_func_t		*rl_startup_hook;
 extern char		*rl_terminal_name;
 extern int		rl_already_prompted;
 extern char		*rl_prompt;
@@ -153,6 +160,7 @@ extern int		_rl_completion_prefix_display_length;
 extern int		_rl_echoing_p;
 extern int		history_max_entries;
 extern char		*rl_display_prompt;
+extern int		rl_erase_empty_line;
 
 /* supported functions */
 char		*readline(const char *);
@@ -180,7 +188,7 @@ int		 history_search_prefix(const char *, int);
 int		 history_search_pos(const char *, int, int);
 int		 read_history(const char *);
 int		 write_history(const char *);
-int		 history_truncate_file (const char *, int);
+int		 history_truncate_file(const char *, int);
 int		 history_expand(char *, char **);
 char	       **history_tokenize(const char *);
 const char	*get_history_event(const char *, int *, int);
@@ -215,7 +223,7 @@ int		 rl_add_defun(const char *, rl_command_func_t *, int);
 HISTORY_STATE	*history_get_history_state(void);
 void		 rl_get_screen_size(int *, int *);
 void		 rl_set_screen_size(int, int);
-char		*rl_filename_completion_function (const char *, int);
+char		*rl_filename_completion_function(const char *, int);
 int		 _rl_abort_internal(void);
 int		 _rl_qsort_string_compare(char **, char **);
 char	       **rl_completion_matches(const char *, rl_compentry_func_t *);
@@ -226,6 +234,13 @@ void		 rl_reset_after_signal(void);
 void		 rl_echo_signal_char(int);
 int		 rl_crlf(void);
 int		 rl_ding(void);
+char 		*rl_copy_text(int, int);
+void		 rl_replace_line(const char *, int);
+int		 rl_delete_text(int, int);
+void 		 rl_message(const char *format, ...)
+    __attribute__((__format__(__printf__, 1, 2)));
+void		 rl_save_prompt(void);
+void		 rl_restore_prompt(void);
 
 /*
  * The following are not implemented
@@ -236,6 +251,7 @@ void		 rl_set_keymap(Keymap);
 Keymap		 rl_make_bare_keymap(void);
 int		 rl_generic_bind(int, const char *, const char *, Keymap);
 int		 rl_bind_key_in_map(int, rl_command_func_t *, Keymap);
+int		 rl_set_key(const char *, rl_command_func_t *, Keymap);
 void		 rl_cleanup_after_signal(void);
 void		 rl_free_line_state(void);
 int		 rl_set_keyboard_input_timeout(int);