diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 175 |
1 files changed, 113 insertions, 62 deletions
@@ -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 |