summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2023-04-27 15:33:37 -0400
committerChet Ramey <chet.ramey@case.edu>2023-04-27 15:33:37 -0400
commitf156385efb545a5ab96a2461555955d7f280aac4 (patch)
tree4c4ede0b0755f46629e1076b884ccf03654f5d47
parent14144013617be12f94b99b05bf0928a8d1eba743 (diff)
downloadreadline-devel.tar.gz
asan updates to non-incremental search, redisplay; rework non-incremental search to avoid pointer aliasing issuesdevel
-rw-r--r--display.c37
-rw-r--r--doc/rltech.texi8
-rw-r--r--doc/rluser.texi32
-rw-r--r--examples/Makefile.in2
-rw-r--r--examples/excallback.c2
-rw-r--r--examples/fileman.c137
-rw-r--r--examples/hist_erasedups.c10
-rw-r--r--examples/hist_purgecmd.c12
-rw-r--r--examples/manexamp.c42
-rw-r--r--examples/rl-callbacktest.c103
-rw-r--r--examples/rl-timeout.c12
-rw-r--r--examples/rl.c8
-rw-r--r--examples/rlcat.c18
-rw-r--r--examples/rlevent.c10
-rw-r--r--examples/rlptytest.c19
-rw-r--r--examples/rltest.c6
-rw-r--r--histexpand.c2
-rw-r--r--history.h6
-rw-r--r--misc.c155
-rw-r--r--rlprivate.h9
-rw-r--r--search.c110
-rw-r--r--text.c5
-rw-r--r--vi_mode.c17
23 files changed, 463 insertions, 299 deletions
diff --git a/display.c b/display.c
index fb10c60..b390fc9 100644
--- a/display.c
+++ b/display.c
@@ -1126,19 +1126,6 @@ rl_redisplay (void)
olen = sprintf (obuf, "\\%o", c);
- if (lpos + olen >= _rl_screenwidth)
- {
- temp = _rl_screenwidth - lpos;
- CHECK_INV_LBREAKS ();
- inv_lbreaks[++newlines] = out + temp;
-#if defined (HANDLE_MULTIBYTE)
- line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn;
-#endif
- lpos = olen - temp;
- }
- else
- lpos += olen;
-
for (temp = 0; temp < olen; temp++)
{
invis_addc (&out, obuf[temp], cur_face);
@@ -2043,6 +2030,8 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
#if defined (HANDLE_MULTIBYTE)
/* Find the last character that is the same between the two lines. This
bounds the region that needs to change. */
+ /* In this case, `last character' means the one farthest from the end of
+ the line. */
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
@@ -2059,7 +2048,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
*olsf != *nlsf)
break;
- if (*ols == ' ')
+ if (*ols != ' ')
wsatend = 0;
ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
@@ -2128,7 +2117,23 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
/* We have moved up to a new screen line. This line may or may not have
invisible characters on it, but we do our best to recalculate
visible_wrap_offset based on what we know. */
- if (current_line == 0)
+ /* This first clause handles the case where the prompt has been
+ recalculated (e.g., by rl_message) but the old prompt is still on
+ the visible line because we haven't overwritten it yet. We want
+ to somehow use the old prompt information, but we only want to do
+ this once. */
+ if (current_line == 0 && saved_local_prompt && old[0] == saved_local_prompt[0] && memcmp (old, saved_local_prompt, saved_local_length) == 0)
+ visible_wrap_offset = saved_invis_chars_first_line;
+ /* This clause handles the opposite: the prompt has been restored (e.g.,
+ by rl_clear_message) but the old saved_local_prompt (now NULL, so we
+ can't directly check it) is still on the visible line because we
+ haven't overwritten it yet. We guess that there aren't any invisible
+ characters in any of the prompts we put in with rl_message */
+ else if (current_line == 0 && local_prompt && new[0] == local_prompt[0] &&
+ (memcmp (new, local_prompt, local_prompt_len) == 0) &&
+ (memcmp (old, local_prompt, local_prompt_len) != 0))
+ visible_wrap_offset = 0;
+ else if (current_line == 0)
visible_wrap_offset = prompt_invis_chars_first_line; /* XXX */
#if 0 /* XXX - not yet */
else if (current_line == prompt_last_screen_line && wrap_offset > prompt_invis_chars_first_line)
@@ -2826,7 +2831,7 @@ _rl_move_cursor_relative (int new, const char *data, const char *dataf)
(prompt_last_invisible) in the last line. IN_INVISLINE is the
offset of DATA in invisible_line */
in_invisline = 0;
- if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1])
+ if (data > invisible_line && _rl_inv_botlin < inv_lbsize && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1])
in_invisline = data - invisible_line;
/* Use NEW when comparing against the last invisible character in the
diff --git a/doc/rltech.texi b/doc/rltech.texi
index db38a31..5aa0453 100644
--- a/doc/rltech.texi
+++ b/doc/rltech.texi
@@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
-Copyright (C) 1988--2022 Free Software Foundation, Inc.
+Copyright (C) 1988--2023 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -2643,7 +2643,7 @@ com_list (char *arg)
if (!arg)
arg = "";
- sprintf (syscom, "ls -FClg %s", arg);
+ snprintf (syscom, sizeof (syscom), "ls -FClg %s", arg);
return (system (syscom));
@}
@@ -2655,9 +2655,9 @@ com_view (char *arg)
#if defined (__MSDOS__)
/* more.com doesn't grok slashes in pathnames */
- sprintf (syscom, "less %s", arg);
+ snprintf (syscom, sizeof (syscom), "less %s", arg);
#else
- sprintf (syscom, "more %s", arg);
+ snprintf (syscom, sizeof (syscom), "more %s", arg);
#endif
return (system (syscom));
@}
diff --git a/doc/rluser.texi b/doc/rluser.texi
index bb1a24f..36e8a38 100644
--- a/doc/rluser.texi
+++ b/doc/rluser.texi
@@ -2106,14 +2106,25 @@ be completed, and two to modify the completion as it is happening.
@item compgen
@btindex compgen
@example
-@code{compgen [@var{option}] [@var{word}]}
+@code{compgen [-V @var{varname}] [@var{option}] [@var{word}]}
@end example
Generate possible completion matches for @var{word} according to
the @var{option}s, which may be any option accepted by the
@code{complete}
-builtin with the exception of @option{-p} and @option{-r}, and write
-the matches to the standard output.
+builtin with the exceptions of
+@option{-p},
+@option{-r},
+@option{-D},
+@option{-E},
+and
+@option{-I},
+and write the matches to the standard output.
+
+If the @option{-V} option is supplied, @code{compgen} stores the generated
+completions into the indexed array variable @var{varname} instead of writing
+them to the standard output.
+
When using the @option{-F} or @option{-C} options, the various shell variables
set by the programmable completion facilities, while available, will not
have useful values.
@@ -2130,9 +2141,9 @@ matches were generated.
@item complete
@btindex complete
@example
-@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}] [-G @var{globpat}]
-[-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}]
-[-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
+@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}]
+[-G @var{globpat}] [-W @var{wordlist}] [-F @var{function}] [-C @var{command}]
+[-X @var{filterpat}] [-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
@code{complete -pr [-DEI] [@var{name} @dots{}]}
@end example
@@ -2338,7 +2349,14 @@ case, any completion not matching @var{filterpat} is removed.
@end table
The return value is true unless an invalid option is supplied, an option
-other than @option{-p} or @option{-r} is supplied without a @var{name}
+other than
+@option{-p},
+@option{-r},
+@option{-D},
+@option{-E},
+or
+@option{-I}
+is supplied without a @var{name}
argument, an attempt is made to remove a completion specification for
a @var{name} for which no specification exists, or
an error occurs adding a completion specification.
diff --git a/examples/Makefile.in b/examples/Makefile.in
index 291c6b7..dc1aba3 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -164,6 +164,7 @@ distclean maintainer-clean: clean
$(RM) Makefile
fileman.o: fileman.c
+manexamp.o: manexamp.c
rltest.o: rltest.c
rltest2.o: rltest2.c
rl.o: rl.c
@@ -179,6 +180,7 @@ rl-callbacktest.o: rl-callbacktest.c
rl-timeout.o: rl-timeout.c
fileman.o: $(top_srcdir)/readline.h
+manexamp.o: $(top_srcdir)/readline.h
rltest.o: $(top_srcdir)/readline.h
rltest2.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rl.o: $(top_srcdir)/readline.h
diff --git a/examples/excallback.c b/examples/excallback.c
index 923c923..04ecb14 100644
--- a/examples/excallback.c
+++ b/examples/excallback.c
@@ -102,7 +102,7 @@ cc_t old_vtime;
struct termios term;
int
-main()
+main(int c, char **v)
{
fd_set fds;
diff --git a/examples/fileman.c b/examples/fileman.c
index 2a8b097..df57945 100644
--- a/examples/fileman.c
+++ b/examples/fileman.c
@@ -1,6 +1,6 @@
/* fileman.c - file manager example for readline library. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -61,24 +61,24 @@
# include <readline/history.h>
#endif
-extern char *xmalloc PARAMS((size_t));
+extern char *xmalloc (size_t);
-void initialize_readline PARAMS((void));
-void too_dangerous PARAMS((char *));
+void initialize_readline (void);
+void too_dangerous (char *);
-int execute_line PARAMS((char *));
-int valid_argument PARAMS((char *, char *));
+int execute_line (char *);
+int valid_argument (char *, char *);
/* The names of functions that actually do the manipulation. */
-int com_list PARAMS((char *));
-int com_view PARAMS((char *));
-int com_rename PARAMS((char *));
-int com_stat PARAMS((char *));
-int com_pwd PARAMS((char *));
-int com_delete PARAMS((char *));
-int com_help PARAMS((char *));
-int com_cd PARAMS((char *));
-int com_quit PARAMS((char *));
+int com_list (char *);
+int com_view (char *);
+int com_rename (char *);
+int com_stat (char *);
+int com_pwd (char *);
+int com_delete (char *);
+int com_help (char *);
+int com_cd (char *);
+int com_quit (char *);
/* A structure which contains information on the commands this program
can understand. */
@@ -105,8 +105,11 @@ COMMAND commands[] = {
};
/* Forward declarations. */
-char *stripwhite ();
-COMMAND *find_command ();
+char *dupstr (char *);
+int execute_line (char *);
+char *stripwhite (char *);
+
+COMMAND *find_command (char *);
/* The name of this program, as taken from argv[0]. */
char *progname;
@@ -115,8 +118,7 @@ char *progname;
int done;
char *
-dupstr (s)
- char *s;
+dupstr (char *s)
{
char *r;
@@ -125,45 +127,9 @@ dupstr (s)
return (r);
}
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- char *line, *s;
-
- progname = argv[0];
-
- initialize_readline (); /* Bind our completer. */
-
- /* Loop reading and executing lines until the user quits. */
- for ( ; done == 0; )
- {
- line = readline ("FileMan: ");
-
- if (!line)
- break;
-
- /* Remove leading and trailing whitespace from the line.
- Then, if there is anything left, add it to the history list
- and execute it. */
- s = stripwhite (line);
-
- if (*s)
- {
- add_history (s);
- execute_line (s);
- }
-
- free (line);
- }
- exit (0);
-}
-
/* Execute a command line. */
int
-execute_line (line)
- char *line;
+execute_line (char *line)
{
register int i;
COMMAND *command;
@@ -202,8 +168,7 @@ execute_line (line)
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
COMMAND *
-find_command (name)
- char *name;
+find_command (char *name)
{
register int i;
@@ -217,8 +182,7 @@ find_command (name)
/* Strip whitespace from the start and end of STRING. Return a pointer
into STRING. */
char *
-stripwhite (string)
- char *string;
+stripwhite (char *string)
{
register char *s, *t;
@@ -242,14 +206,14 @@ stripwhite (string)
/* */
/* **************************************************************** */
-char *command_generator PARAMS((const char *, int));
-char **fileman_completion PARAMS((const char *, int, int));
+char *command_generator (const char *, int);
+char **fileman_completion (const char *, int, int);
/* Tell the GNU Readline library how to complete. We want to try to complete
on command names if this is the first word in the line, or on filenames
if not. */
void
-initialize_readline ()
+initialize_readline (void)
{
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "FileMan";
@@ -264,9 +228,7 @@ initialize_readline ()
in case we want to do some simple parsing. Return the array of matches,
or NULL if there aren't any. */
char **
-fileman_completion (text, start, end)
- const char *text;
- int start, end;
+fileman_completion (const char *text, int start, int end)
{
char **matches;
@@ -285,9 +247,7 @@ fileman_completion (text, start, end)
to start from scratch; without any state (i.e. STATE == 0), then we
start at the top of the list. */
char *
-command_generator (text, state)
- const char *text;
- int state;
+command_generator (const char *text, int state)
{
static int list_index, len;
char *name;
@@ -332,7 +292,7 @@ com_list (arg)
if (!arg)
arg = "";
- sprintf (syscom, "ls -FClg %s", arg);
+ snprintf (syscom, sizeof (syscom), "ls -FClg %s", arg);
return (system (syscom));
}
@@ -345,9 +305,9 @@ com_view (arg)
#if defined (__MSDOS__)
/* more.com doesn't grok slashes in pathnames */
- sprintf (syscom, "less %s", arg);
+ snprintf (syscom, sizeof (syscom), "less %s", arg);
#else
- sprintf (syscom, "more %s", arg);
+ snprintf (syscom, sizeof (syscom), "more %s", arg);
#endif
return (system (syscom));
}
@@ -504,3 +464,36 @@ valid_argument (caller, arg)
return (1);
}
+
+int
+main (int argc, char **argv)
+{
+ char *line, *s;
+
+ progname = argv[0];
+
+ initialize_readline (); /* Bind our completer. */
+
+ /* Loop reading and executing lines until the user quits. */
+ for ( ; done == 0; )
+ {
+ line = readline ("FileMan: ");
+
+ if (!line)
+ break;
+
+ /* Remove leading and trailing whitespace from the line.
+ Then, if there is anything left, add it to the history list
+ and execute it. */
+ s = stripwhite (line);
+
+ if (*s)
+ {
+ add_history (s);
+ execute_line (s);
+ }
+
+ free (line);
+ }
+ exit (0);
+}
diff --git a/examples/hist_erasedups.c b/examples/hist_erasedups.c
index f820eba..717bb7e 100644
--- a/examples/hist_erasedups.c
+++ b/examples/hist_erasedups.c
@@ -1,6 +1,6 @@
/* hist_erasedups -- remove all duplicate entries from history file */
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -41,16 +41,14 @@
int hist_erasedups (void);
static void
-usage()
+usage(void)
{
fprintf (stderr, "hist_erasedups: usage: hist_erasedups [-t] [filename]\n");
exit (2);
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
char *fn;
int r;
@@ -94,7 +92,7 @@ main (argc, argv)
}
int
-hist_erasedups ()
+hist_erasedups (void)
{
int r, n;
HIST_ENTRY *h, *temp;
diff --git a/examples/hist_purgecmd.c b/examples/hist_purgecmd.c
index 7992d81..3adb699 100644
--- a/examples/hist_purgecmd.c
+++ b/examples/hist_purgecmd.c
@@ -1,7 +1,7 @@
/* hist_purgecmd -- remove all instances of command or pattern from history
file */
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -46,16 +46,14 @@
int hist_purgecmd (char *, int);
static void
-usage()
+usage(void)
{
fprintf (stderr, "hist_purgecmd: usage: hist_purgecmd [-r] [-t] [-f filename] command-spec\n");
exit (2);
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
char *fn;
int r, flags;
@@ -109,9 +107,7 @@ main (argc, argv)
}
int
-hist_purgecmd (cmd, flags)
- char *cmd;
- int flags;
+hist_purgecmd (char *cmd, int flags)
{
int r, n, rflags;
HIST_ENTRY *temp;
diff --git a/examples/manexamp.c b/examples/manexamp.c
index 351c628..c8e11d5 100644
--- a/examples/manexamp.c
+++ b/examples/manexamp.c
@@ -1,6 +1,6 @@
/* manexamp.c -- The examples which appear in the documentation are here. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -18,9 +18,35 @@
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+
+#include <stdlib.h>
#include <stdio.h>
-#include <readline/readline.h>
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#ifndef errno
+extern int errno;
+#endif
+
+#if defined (READLINE_LIBRARY)
+# include "readline.h"
+# include "history.h"
+#else
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
/* **************************************************************** */
/* */
@@ -33,7 +59,7 @@ static char *line_read = (char *)NULL;
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
char *
-rl_gets ()
+rl_gets (void)
{
/* If the buffer has already been allocated, return the memory
to the free pool. */
@@ -60,10 +86,11 @@ rl_gets ()
/* **************************************************************** */
/* Invert the case of the COUNT following characters. */
-invert_case_line (count, key)
- int count, key;
+int
+invert_case_line (int count, int key)
{
- register int start, end;
+ int start, end;
+ int direction;
start = rl_point;
@@ -92,7 +119,7 @@ invert_case_line (count, key)
}
if (start == end)
- return;
+ return 0;
/* Tell readline that we are modifying the line, so save the undo
information. */
@@ -108,4 +135,5 @@ invert_case_line (count, key)
/* Move point to on top of the last character changed. */
rl_point = end - direction;
+ return 0;
}
diff --git a/examples/rl-callbacktest.c b/examples/rl-callbacktest.c
index 7febacd..269ed2e 100644
--- a/examples/rl-callbacktest.c
+++ b/examples/rl-callbacktest.c
@@ -1,7 +1,9 @@
/* Standard include files. stdio.h is required. */
+#include <errno.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
+#include <unistd.h>
+#include <locale.h>
/* Used for select(2) */
#include <sys/types.h>
@@ -9,36 +11,37 @@
#include <signal.h>
-#include <errno.h>
#include <stdio.h>
-#include <locale.h>
-
/* Standard readline include files. */
-#if defined (READLINE_LIBRARY)
-# include "readline.h"
-# include "history.h"
-#else
-# include <readline/readline.h>
-# include <readline/history.h>
-#endif
-
-extern int errno;
+#include "readline.h"
+#include "history.h"
static void cb_linehandler (char *);
-static void signandler (int);
+static void sigwinch_handler (int);
+static void sigint_handler (int);
-int running, sigwinch_received;
+int running;
+int sigwinch_received;
+int sigint_received;
const char *prompt = "rltest$ ";
/* Handle SIGWINCH and window size changes when readline is not active and
reading a character. */
static void
-sighandler (int sig)
+sigwinch_handler (int sig)
{
sigwinch_received = 1;
}
+/* Handle SIGWINCH and window size changes when readline is not active and
+ reading a character. */
+static void
+sigint_handler (int sig)
+{
+ sigint_received = 1;
+}
+
/* Callback function called for each line when accept-line executed, EOF
seen, or EOF character read. This sets a flag and returns; it could
also call exit(3). */
@@ -52,8 +55,8 @@ cb_linehandler (char *line)
printf ("\n");
printf ("exit\n");
/* This function needs to be called to reset the terminal settings,
- and calling it from the line handler keeps one extra prompt from
- being displayed. */
+ and calling it from the line handler keeps one extra prompt from
+ being displayed. */
rl_callback_handler_remove ();
running = 0;
@@ -61,23 +64,45 @@ cb_linehandler (char *line)
else
{
if (*line)
- add_history (line);
+ add_history (line);
printf ("input line: %s\n", line);
free (line);
}
}
+int count = 2;
+
+static int
+my_getc (FILE *stream)
+{
+ if (--count == 0)
+ {
+ kill (getpid (), SIGINT);
+ }
+
+ int ch = rl_getc (stream);
+
+ return ch;
+}
+
+
int
main (int c, char **v)
{
fd_set fds;
int r;
+ /* Set the default locale values according to environment variables. */
setlocale (LC_ALL, "");
- /* Handle SIGWINCH */
- signal (SIGWINCH, sighandler);
-
+ /* Handle window size changes when readline is not active and reading
+ characters. */
+ signal (SIGWINCH, sigwinch_handler);
+
+ signal (SIGINT, sigint_handler);
+
+ rl_getc_function = my_getc;
+
/* Install the line handler. */
rl_callback_handler_install (prompt, cb_linehandler);
@@ -89,25 +114,35 @@ main (int c, char **v)
while (running)
{
FD_ZERO (&fds);
- FD_SET (fileno (rl_instream), &fds);
+ FD_SET (fileno (rl_instream), &fds);
r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
if (r < 0 && errno != EINTR)
- {
- perror ("rltest: select");
- rl_callback_handler_remove ();
- break;
- }
+ {
+ perror ("rltest: select");
+ rl_callback_handler_remove ();
+ break;
+ }
if (sigwinch_received)
- {
- rl_resize_terminal ();
- sigwinch_received = 0;
- }
+ {
+ rl_resize_terminal ();
+ sigwinch_received = 0;
+ }
+ if (sigint_received)
+ {
+ printf ("Quit\n");
+
+ rl_callback_handler_remove ();
+ rl_callback_handler_install (prompt, cb_linehandler);
+
+ sigint_received = 0;
+ continue;
+ }
if (r < 0)
- continue;
+ continue;
if (FD_ISSET (fileno (rl_instream), &fds))
- rl_callback_read_char ();
+ rl_callback_read_char ();
}
printf ("rltest: Event loop has exited\n");
diff --git a/examples/rl-timeout.c b/examples/rl-timeout.c
index b8a24ba..81f00f5 100644
--- a/examples/rl-timeout.c
+++ b/examples/rl-timeout.c
@@ -56,7 +56,7 @@ const char *prompt = "rl-timeout$ ";
/* **************************************************************** */
void
-rltest_timeout_readline1 ()
+rltest_timeout_readline1 (void)
{
const char *temp;
@@ -78,14 +78,14 @@ rltest_timeout_readline1 ()
/* **************************************************************** */
static int
-timeout_handler ()
+timeout_handler (void)
{
printf ("timeout\n");
return READERR;
}
void
-rltest_timeout_readline2 ()
+rltest_timeout_readline2 (void)
{
const char *temp;
@@ -134,7 +134,7 @@ cb_linehandler (char *line)
}
void
-rltest_timeout_callback1 ()
+rltest_timeout_callback1 (void)
{
fd_set fds;
int r;
@@ -180,7 +180,7 @@ rltest_timeout_callback1 ()
/* **************************************************************** */
static int
-cb_timeouthandler ()
+cb_timeouthandler (void)
{
printf ("timeout\n");
rl_callback_handler_remove ();
@@ -189,7 +189,7 @@ cb_timeouthandler ()
}
void
-rltest_timeout_callback2 ()
+rltest_timeout_callback2 (void)
{
int r;
diff --git a/examples/rl.c b/examples/rl.c
index e04bbd6..dd8f88d 100644
--- a/examples/rl.c
+++ b/examples/rl.c
@@ -59,7 +59,7 @@ static char *progname;
static char *deftext;
static int
-set_deftext ()
+set_deftext (void)
{
if (deftext)
{
@@ -71,16 +71,14 @@ set_deftext ()
}
static void
-usage()
+usage(void)
{
fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
progname, progname);
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
char *temp, *prompt;
struct stat sb;
diff --git a/examples/rlcat.c b/examples/rlcat.c
index f1b0362..419a197 100644
--- a/examples/rlcat.c
+++ b/examples/rlcat.c
@@ -4,7 +4,7 @@
* usage: rlcat
*/
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -64,21 +64,20 @@ extern int errno;
extern int optind;
extern char *optarg;
-static int stdcat();
+static int fcopy(FILE *);
+static int stdcat(int, char **);
static char *progname;
static int vflag;
static void
-usage()
+usage(void)
{
fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
char *temp;
int opt, Vflag, Nflag;
@@ -134,8 +133,7 @@ main (argc, argv)
}
static int
-fcopy(fp)
- FILE *fp;
+fcopy(FILE *fp)
{
int c;
char *x;
@@ -155,9 +153,7 @@ fcopy(fp)
}
int
-stdcat (argc, argv)
- int argc;
- char **argv;
+stdcat (int argc, char **argv)
{
int i, fd, r;
char *s;
diff --git a/examples/rlevent.c b/examples/rlevent.c
index 1b7f4eb..57e4b4b 100644
--- a/examples/rlevent.c
+++ b/examples/rlevent.c
@@ -69,7 +69,7 @@ static char *progname;
static char *deftext;
static int
-event_hook ()
+event_hook (void)
{
fprintf (stderr, "ding!\n");
sleep (1);
@@ -77,7 +77,7 @@ event_hook ()
}
static int
-set_deftext ()
+set_deftext (void)
{
if (deftext)
{
@@ -89,16 +89,14 @@ set_deftext ()
}
static void
-usage()
+usage(void)
{
fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
progname, progname);
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
char *temp, *prompt;
struct stat sb;
diff --git a/examples/rlptytest.c b/examples/rlptytest.c
index d170f62..021a868 100644
--- a/examples/rlptytest.c
+++ b/examples/rlptytest.c
@@ -42,8 +42,7 @@ static int masterfd = -1;
static int slavefd;
void
-sigint (s)
- int s;
+sigint (int s)
{
tty_reset (STDIN_FILENO);
close (masterfd);
@@ -53,14 +52,13 @@ sigint (s)
}
void
-sigwinch (s)
- int s;
+sigwinch (int s)
{
rl_resize_terminal ();
}
static int
-user_input()
+user_input(void)
{
int size;
const int MAX = 1024;
@@ -78,7 +76,7 @@ user_input()
}
static int
-readline_input()
+readline_input(void)
{
const int MAX = 1024;
char *buf = (char *)malloc(MAX+1);
@@ -124,7 +122,7 @@ rlctx_send_user_command(char *line)
}
static void
-custom_deprep_term_function ()
+custom_deprep_term_function (void)
{
}
@@ -226,9 +224,10 @@ static enum { RESET, TCBREAK } ttystate = RESET;
*
* Returns: 0 on success, -1 on error
*/
-int tty_cbreak(int fd){
+int tty_cbreak(int fd)
+{
struct termios buf;
- int ttysavefd = -1;
+ int ttysavefd = -1;
if(tcgetattr(fd, &save_termios) < 0)
return -1;
@@ -316,7 +315,7 @@ int tty_reset(int fd)
}
int
-main()
+main(int c, char **v)
{
int val;
diff --git a/examples/rltest.c b/examples/rltest.c
index 8b7c00c..feab90f 100644
--- a/examples/rltest.c
+++ b/examples/rltest.c
@@ -4,7 +4,7 @@
/* */
/* **************************************************************** */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
@@ -48,10 +48,8 @@ extern void exit();
# include <readline/history.h>
#endif
-extern HIST_ENTRY **history_list ();
-
int
-main ()
+main (int c, char **v)
{
char *temp, *prompt;
int done;
diff --git a/histexpand.c b/histexpand.c
index f2eb18f..db344b4 100644
--- a/histexpand.c
+++ b/histexpand.c
@@ -730,7 +730,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p
/* If `&' appears in the rhs, it's supposed to be replaced
with the lhs. */
- if (member ('&', subst_rhs))
+ if (subst_lhs && member ('&', subst_rhs))
postproc_subst_rhs ();
}
else
diff --git a/history.h b/history.h
index 49e1bf2..0f275a8 100644
--- a/history.h
+++ b/history.h
@@ -1,6 +1,6 @@
/* history.h -- the names of functions that you can call in history. */
-/* Copyright (C) 1989-2022 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -50,6 +50,10 @@ typedef struct _hist_entry {
histdata_t data;
} HIST_ENTRY;
+#ifndef HIST_ENTRY_DEFINED
+# define HIST_ENTRY_DEFINED
+#endif
+
/* Size of the history-library-managed space in history entry HS. */
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
diff --git a/misc.c b/misc.c
index e1cceca..6e9e030 100644
--- a/misc.c
+++ b/misc.c
@@ -1,6 +1,6 @@
/* misc.c -- miscellaneous bindable readline functions. */
-/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -307,9 +307,7 @@ void
_rl_start_using_history (void)
{
using_history ();
- if (_rl_saved_line_for_history)
- _rl_free_saved_history_line ();
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+ _rl_free_saved_history_line ();
_rl_history_search_pos = -99; /* some random invalid history position */
}
@@ -352,60 +350,71 @@ rl_maybe_replace_line (void)
return 0;
}
+void
+_rl_unsave_line (HIST_ENTRY *entry)
+{
+ /* Can't call with `1' because rl_undo_list might point to an undo
+ list from a history entry, as in rl_replace_from_history() below. */
+ rl_replace_line (entry->line, 0);
+ rl_undo_list = (UNDO_LIST *)entry->data;
+
+ /* Doesn't free `data'. */
+ _rl_free_history_entry (entry);
+
+ rl_point = rl_end; /* rl_replace_line sets rl_end */
+}
+
/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line (void)
{
if (_rl_saved_line_for_history)
{
- /* Can't call with `1' because rl_undo_list might point to an undo
- list from a history entry, as in rl_replace_from_history() below. */
- rl_replace_line (_rl_saved_line_for_history->line, 0);
- rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
-
- /* Doesn't free `data'. */
- _rl_free_history_entry (_rl_saved_line_for_history);
+ _rl_unsave_line (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- rl_point = rl_end; /* rl_replace_line sets rl_end */
}
else
rl_ding ();
return 0;
}
+HIST_ENTRY *
+_rl_alloc_saved_line (void)
+{
+ HIST_ENTRY *ret;
+
+ ret = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+
+ ret->line = savestring (rl_line_buffer);
+ ret->timestamp = (char *)NULL;
+ ret->data = (char *)rl_undo_list;
+
+ return ret;
+}
+
/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line (void)
{
if (_rl_saved_line_for_history == 0)
- {
- _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
- _rl_saved_line_for_history->line = savestring (rl_line_buffer);
- _rl_saved_line_for_history->timestamp = (char *)NULL;
- _rl_saved_line_for_history->data = (char *)rl_undo_list;
- }
+ _rl_saved_line_for_history = _rl_alloc_saved_line ();
return 0;
}
+/* Just a wrapper, any self-respecting compiler will inline it. */
+void
+_rl_free_saved_line (HIST_ENTRY *entry)
+{
+ _rl_free_history_entry (entry);
+}
+
int
_rl_free_saved_history_line (void)
{
- if (_rl_saved_line_for_history)
- {
- UNDO_LIST *sentinel;
-
- sentinel = (UNDO_LIST *)_rl_saved_line_for_history->data;
-
- /* We should only free `data' if it's not the current rl_undo_list and
- it's not the `data' member in a history entry somewhere. We have to
- free it separately because only the callers know it's an undo list. */
- if (sentinel && sentinel != rl_undo_list && _hs_search_history_data ((histdata_t *)sentinel) < 0)
- _rl_free_undo_list (sentinel);
+ _rl_free_saved_line (_rl_saved_line_for_history);
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- }
return 0;
}
@@ -563,20 +572,11 @@ rl_end_of_history (int count, int key)
return 0;
}
-/* Move down to the next history line. */
int
-rl_get_next_history (int count, int key)
+_rl_next_history_internal (int count)
{
HIST_ENTRY *temp;
- if (count < 0)
- return (rl_get_previous_history (-count, key));
-
- if (count == 0)
- return 0;
-
- rl_maybe_replace_line ();
-
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
@@ -591,41 +591,48 @@ rl_get_next_history (int count, int key)
}
if (temp == 0)
- rl_maybe_unsave_line ();
+ return 0;
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
+ return 1;
}
- return 0;
}
-/* Get the previous item out of our interactive history, making it the current
- line. If there is no previous history, just ding. */
+/* Move down to the next history line. */
int
-rl_get_previous_history (int count, int key)
+rl_get_next_history (int count, int key)
{
- HIST_ENTRY *old_temp, *temp;
- int had_saved_line;
+ int r;
if (count < 0)
- return (rl_get_next_history (-count, key));
+ return (rl_get_previous_history (-count, key));
- if (count == 0 || history_list () == 0)
+ if (count == 0)
return 0;
- /* either not saved by rl_newline or at end of line, so set appropriately. */
- if (_rl_history_saved_point == -1 && (rl_point || rl_end))
- _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+ rl_maybe_replace_line ();
- /* If we don't have a line saved, then save this one. */
- had_saved_line = _rl_saved_line_for_history != 0;
- rl_maybe_save_line ();
+ r = _rl_next_history_internal (count);
- /* If the current line has changed, save the changes. */
- rl_maybe_replace_line ();
+ if (r == 0)
+ rl_maybe_unsave_line ();
+
+ return 0;
+}
+
+int
+_rl_previous_history_internal (int count)
+{
+ HIST_ENTRY *old_temp, *temp;
temp = old_temp = (HIST_ENTRY *)NULL;
+
+ /* either not saved by rl_newline or at end of line, so set appropriately. */
+ if (_rl_history_saved_point == -1 && (rl_point || rl_end))
+ _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+
while (count)
{
temp = previous_history ();
@@ -643,15 +650,41 @@ rl_get_previous_history (int count, int key)
if (temp == 0)
{
- if (had_saved_line == 0)
- _rl_free_saved_history_line ();
rl_ding ();
+ return 0;
}
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
+ return 1;
}
+}
+
+/* Get the previous item out of our interactive history, making it the current
+ line. If there is no previous history, just ding. */
+int
+rl_get_previous_history (int count, int key)
+{
+ int had_saved_line, r;
+
+ if (count < 0)
+ return (rl_get_next_history (-count, key));
+
+ if (count == 0 || history_list () == 0)
+ return 0;
+
+ /* If we don't have a line saved, then save this one. */
+ had_saved_line = _rl_saved_line_for_history != 0;
+ rl_maybe_save_line ();
+
+ /* If the current line has changed, save the changes. */
+ rl_maybe_replace_line ();
+
+ r = _rl_previous_history_internal (count);
+
+ if (r == 0 && had_saved_line == 0) /* failed to find previous history */
+ _rl_free_saved_history_line ();
return 0;
}
diff --git a/rlprivate.h b/rlprivate.h
index 5c0592b..c3e43e3 100644
--- a/rlprivate.h
+++ b/rlprivate.h
@@ -369,7 +369,13 @@ extern int _rl_arg_callback (_rl_arg_cxt);
extern void _rl_reset_argument (void);
extern void _rl_start_using_history (void);
+#if defined (HIST_ENTRY_DEFINED)
+extern HIST_ENTRY *_rl_alloc_saved_line (void);
+extern void _rl_free_saved_line (HIST_ENTRY *);
+extern void _rl_unsave_line (HIST_ENTRY *);
+#endif
extern int _rl_free_saved_history_line (void);
+
extern void _rl_set_insert_mode (int, int);
extern void _rl_revert_previous_lines (void);
@@ -406,6 +412,8 @@ extern int _rl_restore_tty_signals (void);
extern int _rl_nsearch_callback (_rl_search_cxt *);
extern int _rl_nsearch_cleanup (_rl_search_cxt *, int);
+extern void _rl_free_saved_search_line (void);
+
/* signals.c */
extern void _rl_signal_handler (int);
@@ -526,6 +534,7 @@ extern int _rl_menu_complete_prefix_first;
/* display.c */
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
+extern int _rl_last_v_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
diff --git a/search.c b/search.c
index 965722b..810ab41 100644
--- a/search.c
+++ b/search.c
@@ -1,6 +1,6 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
-/* Copyright (C) 1992-2022 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -55,6 +55,8 @@
_rl_search_cxt *_rl_nscxt = 0;
+static HIST_ENTRY *_rl_saved_line_for_search;
+
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos;
@@ -78,23 +80,57 @@ static _rl_search_cxt *_rl_nsearch_init (int, int);
static void _rl_nsearch_abort (_rl_search_cxt *);
static int _rl_nsearch_dispatch (_rl_search_cxt *, int);
+void
+_rl_free_saved_search_line (void)
+{
+ if (_rl_saved_line_for_search)
+ _rl_free_saved_line (_rl_saved_line_for_search);
+ _rl_saved_line_for_search = (HIST_ENTRY *)NULL;
+}
+
+static inline void
+_rl_unsave_saved_search_line (void)
+{
+ if (_rl_saved_line_for_search)
+ _rl_unsave_line (_rl_saved_line_for_search);
+ _rl_saved_line_for_search = (HIST_ENTRY *)NULL;
+}
+
+/* We're going to replace the undo list with the one created by inserting
+ the matching line we found, so we want to free rl_undo_list if it's not
+ from a history entry. We assume the undo list does not come from a
+ history entry if we are at the end of the history, entering a new line.
+
+ The call to rl_maybe_replace_line() has already ensured that any undo
+ list pointing to a history entry has already been saved back to the
+ history and set rl_undo_list to NULL. */
+
+static void
+dispose_saved_search_line (void)
+{
+ UNDO_LIST *xlist;
+
+ if (_hs_at_end_of_history () == 0)
+ _rl_unsave_saved_search_line ();
+ else if (_rl_saved_line_for_search)
+ {
+ xlist = _rl_saved_line_for_search ? (UNDO_LIST *)_rl_saved_line_for_search->data : 0;
+ if (xlist)
+ _rl_free_undo_list (xlist);
+ _rl_saved_line_for_search->data = 0;
+ _rl_free_saved_search_line ();
+ }
+}
+
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (HIST_ENTRY *entry)
{
- UNDO_LIST *xlist;
-
- xlist = _rl_saved_line_for_history ? (UNDO_LIST *)_rl_saved_line_for_history->data : 0;
- /* At this point, rl_undo_list points to a private search string list. */
- if (rl_undo_list && rl_undo_list != (UNDO_LIST *)entry->data && rl_undo_list != xlist &&
- _hs_search_history_data ((histdata_t *)rl_undo_list) < 0)
- rl_free_undo_list ();
- rl_undo_list = 0; /* XXX */
-
/* Now we create a new undo list with a single insert for this text.
WE DON'T CHANGE THE ORIGINAL HISTORY ENTRY UNDO LIST */
+ rl_undo_list = 0; /* XXX */
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
@@ -105,15 +141,6 @@ make_history_line_current (HIST_ENTRY *entry)
current editing buffer. */
rl_free_undo_list ();
#endif
-
- /* This will need to free the saved undo list associated with the original
- (pre-search) line buffer.
- XXX - look at _rl_free_saved_history_line and consider calling it if
- rl_undo_list != xlist (or calling rl_free_undo list directly on
- _rl_saved_line_for_history->data) */
- if (_rl_saved_line_for_history)
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search the history list for STRING starting at absolute history position
@@ -185,7 +212,7 @@ noninc_dosearch (char *string, int dir, int flags)
if (pos == -1)
{
/* Search failed, current history position unchanged. */
- rl_maybe_unsave_line ();
+ _rl_unsave_saved_search_line ();
rl_clear_message ();
rl_point = 0;
rl_ding ();
@@ -194,6 +221,10 @@ noninc_dosearch (char *string, int dir, int flags)
noninc_history_pos = pos;
+ /* We're committed to making the line we found the current contents of
+ rl_line_buffer. We can dispose of _rl_saved_line_for_search. */
+ dispose_saved_search_line ();
+
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history (); /* will never be NULL after successful search */
@@ -240,7 +271,10 @@ _rl_nsearch_init (int dir, int pchar)
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
- rl_maybe_save_line ();
+ /* If the current line has changed, put it back into the history if necessary. */
+ rl_maybe_replace_line ();
+
+ _rl_saved_line_for_search = _rl_alloc_saved_line ();
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
@@ -276,7 +310,7 @@ _rl_nsearch_cleanup (_rl_search_cxt *cxt, int r)
static void
_rl_nsearch_abort (_rl_search_cxt *cxt)
{
- rl_maybe_unsave_line ();
+ _rl_unsave_saved_search_line ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
@@ -380,6 +414,7 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt)
{
if (noninc_search_string == 0)
{
+ _rl_free_saved_search_line ();
rl_ding ();
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
@@ -393,12 +428,17 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt)
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
- /* If we don't want the subsequent undo list generated by the search
+ /* We don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
- we need to clear rl_line_buffer here. For now, we just clear the
- undo list generated by reading the search string. (If the search
- fails, the old undo list will be restored by rl_maybe_unsave_line.) */
+ so we need to clear rl_line_buffer here. If we don't want that,
+ change the #if 1 to an #if 0 below. We clear the undo list
+ generated by reading the search string. (If the search fails, the
+ old undo list will be restored by _rl_unsave_line.) */
+
rl_free_undo_list ();
+#if 1
+ rl_line_buffer[rl_point = rl_end = 0] = '\0';
+#endif
}
rl_restore_prompt ();
@@ -534,11 +574,12 @@ rl_history_search_internal (int count, int dir)
{
HIST_ENTRY *temp;
int ret, oldpos, newcol;
- int had_saved_line;
char *t;
- had_saved_line = _rl_saved_line_for_history != 0;
- rl_maybe_save_line ();
+ /* If the current line has changed, put it back into the history if necessary. */
+ rl_maybe_replace_line ();
+
+ _rl_saved_line_for_search = _rl_alloc_saved_line ();
temp = (HIST_ENTRY *)NULL;
/* Search COUNT times through the history for a line matching
@@ -570,8 +611,7 @@ rl_history_search_internal (int count, int dir)
/* If we didn't find anything at all, return. */
if (temp == 0)
{
- /* XXX - check had_saved_line here? */
- rl_maybe_unsave_line ();
+ _rl_unsave_saved_search_line ();
rl_ding ();
/* If you don't want the saved history line (last match) to show up
in the line buffer after the search fails, change the #if 0 to
@@ -584,12 +624,16 @@ rl_history_search_internal (int count, int dir)
rl_mark = 0;
}
#else
- rl_point = _rl_history_search_len; /* rl_maybe_unsave_line changes it */
+ rl_point = _rl_history_search_len; /* _rl_unsave_line changes it */
rl_mark = rl_end;
#endif
return 1;
}
+ /* We're committed to making the line we found the current contents of
+ rl_line_buffer. We can dispose of _rl_saved_line_for_search. */
+ dispose_saved_search_line ();
+
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
@@ -634,7 +678,7 @@ rl_history_search_reinit (int flags)
strncpy (history_search_string + sind, rl_line_buffer, rl_point);
history_search_string[rl_point + sind] = '\0';
}
- _rl_free_saved_history_line (); /* XXX rl_undo_list? */
+ _rl_free_saved_search_line ();
}
/* Search forward in the history for the string of characters
diff --git a/text.c b/text.c
index 62e4da2..356cac5 100644
--- a/text.c
+++ b/text.c
@@ -1229,11 +1229,12 @@ _rl_rubout_char (int count, int key)
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, orig_point);
/* The erase-at-end-of-line hack is of questionable merit now. */
- if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
+ if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos && _rl_last_v_pos == 0)
{
int l;
l = rl_character_len (c, rl_point);
- _rl_erase_at_end_of_line (l);
+ if (_rl_last_c_pos >= l)
+ _rl_erase_at_end_of_line (l);
}
}
else
diff --git a/vi_mode.c b/vi_mode.c
index 7396e31..762a214 100644
--- a/vi_mode.c
+++ b/vi_mode.c
@@ -367,12 +367,12 @@ rl_vi_search (int count, int key)
switch (key)
{
case '?':
- _rl_free_saved_history_line ();
+ _rl_free_saved_search_line (); /* just in case */
rl_noninc_forward_search (count, key);
break;
case '/':
- _rl_free_saved_history_line ();
+ _rl_free_saved_search_line ();
rl_noninc_reverse_search (count, key);
break;
@@ -1090,6 +1090,7 @@ _rl_vi_arg_dispatch (int c)
}
else
{
+ rl_restore_prompt ();
rl_clear_message ();
rl_stuff_char (key);
return 0; /* done */
@@ -1320,7 +1321,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
/* Readine vi motion char starting numeric argument */
else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
{
- RL_SETSTATE (RL_STATE_NUMERICARG);
+ _rl_arg_init ();
return (_rl_vi_arg_dispatch (c));
}
#endif
@@ -1330,7 +1331,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
- RL_SETSTATE (RL_STATE_NUMERICARG);
+ _rl_arg_init ();
rl_digit_loop1 ();
rl_numeric_arg *= save;
c = rl_vi_domove_getchar (m);
@@ -1339,6 +1340,13 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
m->motion = 0;
return -1;
}
+ else if (member (c, vi_motion) == 0)
+ {
+ m->motion = 0;
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ RL_UNSETSTATE (RL_STATE_NUMERICARG);
+ return (1);
+ }
m->motion = c;
return (rl_domove_motion_callback (m));
}
@@ -1363,6 +1371,7 @@ _rl_vi_domove_callback (_rl_vimotion_cxt *m)
int c, r;
m->motion = c = rl_vi_domove_getchar (m);
+
if (c < 0)
return 1; /* EOF */
r = rl_domove_read_callback (m);