- 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
+
(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
/* 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.
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))
/* 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.
_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 */
}
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;
}
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;
}
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 ();
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;
}
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);
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);
/* 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.
_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;
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)
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
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 ();
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 */
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
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 ();
{
if (noninc_search_string == 0)
{
+ _rl_free_saved_search_line ();
rl_ding ();
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
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 ();
{
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
/* 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
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);
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
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;
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));
}
int c, r;
m->motion = c = rl_vi_domove_getchar (m);
+
if (c < 0)
return 1; /* EOF */
r = rl_domove_read_callback (m);