summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c175
1 files changed, 113 insertions, 62 deletions
diff --git a/misc.c b/misc.c
index 4bca9c5..96c82b5 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-2024 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.
@@ -150,6 +150,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
if (_rl_digit_p (c))
{
+ _rl_add_executing_keyseq (key);
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
@@ -157,6 +158,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
}
else if (c == '-' && rl_explicit_arg == 0)
{
+ _rl_add_executing_keyseq (key);
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
@@ -235,6 +237,7 @@ rl_digit_argument (int ignore, int key)
else
{
rl_execute_next (key);
+ _rl_del_executing_keyseq ();
return (rl_digit_loop ());
}
}
@@ -306,9 +309,11 @@ 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;
+#if 1
+ if (_rl_saved_line_for_history && _rl_saved_line_for_history->data)
+ _rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
+#endif
+ _rl_free_saved_history_line ();
_rl_history_search_pos = -99; /* some random invalid history position */
}
@@ -339,64 +344,83 @@ rl_maybe_replace_line (void)
xfree (temp->line);
FREE (temp->timestamp);
xfree (temp);
+ /* What about _rl_saved_line_for_history? if the saved undo list is
+ rl_undo_list, and we just put that into a history entry, should
+ we set the saved undo list to NULL? */
+ if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == rl_undo_list)
+ _rl_saved_line_for_history->data = 0;
+ /* Do we want to set rl_undo_list = 0 here since we just saved it into
+ a history entry? */
+ rl_undo_list = 0;
}
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)
{
- UNDO_LIST *orig;
+ _rl_free_saved_line (_rl_saved_line_for_history);
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- if (_rl_saved_line_for_history)
- {
- if (rl_undo_list && rl_undo_list == (UNDO_LIST *)_rl_saved_line_for_history->data)
- rl_undo_list = 0;
- /* Have to free this separately because _rl_free_history entry can't:
- it doesn't know whether or not this has application data. Only the
- callers that know this is _rl_saved_line_for_history can know that
- it's an undo list. */
- if (_rl_saved_line_for_history->data)
- _rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- }
return 0;
}
@@ -554,20 +578,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;
@@ -582,41 +597,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 ();
@@ -634,15 +656,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;
}
@@ -693,7 +741,7 @@ static int saved_history_logical_offset = -1;
#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
static int
-set_saved_history ()
+set_saved_history (void)
{
int absolute_offset, count;
@@ -762,7 +810,10 @@ _rl_set_insert_mode (int im, int force)
_rl_set_cursor (im, force);
#endif
+ RL_UNSETSTATE (RL_STATE_OVERWRITE);
rl_insert_mode = im;
+ if (rl_insert_mode == RL_IM_OVERWRITE)
+ RL_SETSTATE (RL_STATE_OVERWRITE);
}
/* Toggle overwrite mode. A positive explicit argument selects overwrite