mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-04 19:00:50 +02:00
changes to non-incremental searching to avoid pointer alias problems, undo issues
This commit is contained in:
@@ -6103,3 +6103,63 @@ bashline.c
|
||||
- name_is_acceptable: allow FIGNORE suffixes to match the entire
|
||||
pathname like tcsh does instead of requiring a non-empty prefix.
|
||||
From Emanuele Torre <torreemanuele6@gmail.com>
|
||||
|
||||
4/23
|
||||
----
|
||||
lib/readline/misc.c
|
||||
- _rl_unsave_line: new function, takes a HIST_ENTRY * as an argument,
|
||||
generalized rl_maybe_unsave_line
|
||||
- _rl_alloc_saved_line: allocate a new HIST_ENTRY *, populate it like
|
||||
rl_saved_line_for_history
|
||||
- _rl_free_saved_line: free a saved HIST_ENTRY *
|
||||
- _rl_free_saved_history_line: call _rl_free_saved_line
|
||||
- _rl_previous_history_internal: new function, internals of
|
||||
rl_get_previous_history; change rl_get_previous_history to call it
|
||||
|
||||
lib/readline/history.h
|
||||
- HIST_ENTRY_DEFINED: define sentinel if HIST_ENTRY struct defined
|
||||
|
||||
lib/readline/rlprivate.h
|
||||
- _rl_alloc_saved_line,_rl_free_saved_line,_rl_unsave_line: new extern
|
||||
function definitions
|
||||
- _rl_free_saved_search_line: new extern definition
|
||||
|
||||
lib/readline/search.c
|
||||
- _rl_saved_line_for_search: use private storage to save current line,
|
||||
avoid clashes with rl_saved_line_for_history
|
||||
- _rl_free_saved_search_line,_rl_unsave_saved_search_line: new functions
|
||||
to manage _rl_saved_line_for_search
|
||||
- noninc_dosearch,_rl_nsearch_abort: clean up _rl_saved_line_for_search
|
||||
instead of rl_saved_line_for_history
|
||||
- rl_history_search_internal: allocate private _rl_saved_line_for_search;
|
||||
unsave or free it as appropriate
|
||||
- _rl_history_search_reinit: free up any _rl_saved_line_for_search just
|
||||
in case
|
||||
|
||||
lib/readline/vi_mode.c
|
||||
- rl_vi_search: free _rl_saved_line_for_search, since that's what the
|
||||
non-incremental search functions use now
|
||||
- rl_domove_read_callback: if we read a numeric argument, then a motion
|
||||
character, make sure the motion character is valid before returning
|
||||
it and going on
|
||||
From a report by minipython <599192367@qq.com>
|
||||
|
||||
4/27
|
||||
----
|
||||
lib/readline/display.c
|
||||
- _rl_move_cursor_relative: when checking to see whether data is within
|
||||
the invisible line, make sure to stay within the invisible line
|
||||
line break boundaries
|
||||
|
||||
lib/readline/search.c
|
||||
- dispose_saved_search_line: new function, either unsave the saved
|
||||
search line (if we're not at the end of the history) or free it
|
||||
(if we are). Needs to be immediately followed by call to
|
||||
make_history_line_current, which resets rl_undo_list
|
||||
- make_history_line_current: change strategy: rely on callers to
|
||||
manage _rl_saved_line_for_search and rl_undo_list; just copy the
|
||||
data from the passed history entry into the line buffer and reset
|
||||
rl_undo_list
|
||||
- noninc_dosearch,rl_history_search_internal: call dispose_saved_search_line
|
||||
before calling make_history_line_current
|
||||
|
||||
|
||||
@@ -2831,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
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
+95
-62
@@ -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;
|
||||
_rl_free_saved_line (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
|
||||
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_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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move down to the next history line. */
|
||||
int
|
||||
rl_get_next_history (int count, int key)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_previous_history (-count, key));
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
r = _rl_next_history_internal (count);
|
||||
|
||||
if (r == 0)
|
||||
rl_maybe_unsave_line ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
_rl_previous_history_internal (int count)
|
||||
{
|
||||
HIST_ENTRY *old_temp, *temp;
|
||||
int had_saved_line;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_next_history (-count, key));
|
||||
|
||||
if (count == 0 || history_list () == 0)
|
||||
return 0;
|
||||
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;
|
||||
|
||||
/* 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 ();
|
||||
|
||||
temp = old_temp = (HIST_ENTRY *)NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+77
-33
@@ -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
|
||||
|
||||
+10
-2
@@ -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;
|
||||
|
||||
@@ -1340,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));
|
||||
}
|
||||
@@ -1364,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);
|
||||
|
||||
Reference in New Issue
Block a user