version 1.1.1.2, 2016/11/03 13:35:37
|
version 1.1.1.3, 2021/03/17 01:01:01
|
Line 1
|
Line 1
|
/* misc.c -- miscellaneous bindable readline functions. */ |
/* misc.c -- miscellaneous bindable readline functions. */ |
|
|
/* Copyright (C) 1987-2012 Free Software Foundation, Inc. | /* Copyright (C) 1987-2019 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 56
|
Line 56
|
static int rl_digit_loop PARAMS((void)); |
static int rl_digit_loop PARAMS((void)); |
static void _rl_history_set_point PARAMS((void)); |
static void _rl_history_set_point PARAMS((void)); |
|
|
extern int history_offset; |
|
|
|
/* Forward declarations used in this file */ |
/* Forward declarations used in this file */ |
void _rl_free_history_entry PARAMS((HIST_ENTRY *)); |
void _rl_free_history_entry PARAMS((HIST_ENTRY *)); |
|
|
Line 78 int _rl_history_saved_point = -1;
|
Line 76 int _rl_history_saved_point = -1;
|
/* **************************************************************** */ |
/* **************************************************************** */ |
|
|
int |
int |
_rl_arg_overflow () | _rl_arg_overflow (void) |
{ |
{ |
if (rl_numeric_arg > 1000000) |
if (rl_numeric_arg > 1000000) |
{ |
{ |
Line 94 _rl_arg_overflow ()
|
Line 92 _rl_arg_overflow ()
|
} |
} |
|
|
void |
void |
_rl_arg_init () | _rl_arg_init (void) |
{ |
{ |
rl_save_prompt (); |
rl_save_prompt (); |
_rl_argcxt = 0; |
_rl_argcxt = 0; |
Line 102 _rl_arg_init ()
|
Line 100 _rl_arg_init ()
|
} |
} |
|
|
int |
int |
_rl_arg_getchar () | _rl_arg_getchar (void) |
{ |
{ |
int c; |
int c; |
|
|
Line 118 _rl_arg_getchar ()
|
Line 116 _rl_arg_getchar ()
|
argument should be aborted, 0 if we should not read any more chars, and |
argument should be aborted, 0 if we should not read any more chars, and |
1 if we should continue to read chars. */ |
1 if we should continue to read chars. */ |
int |
int |
_rl_arg_dispatch (cxt, c) | _rl_arg_dispatch (_rl_arg_cxt cxt, int c) |
_rl_arg_cxt cxt; | |
int c; | |
{ |
{ |
int key, r; |
int key, r; |
|
|
Line 128 _rl_arg_dispatch (cxt, c)
|
Line 124 _rl_arg_dispatch (cxt, c)
|
|
|
/* If we see a key bound to `universal-argument' after seeing digits, |
/* If we see a key bound to `universal-argument' after seeing digits, |
it ends the argument but is otherwise ignored. */ |
it ends the argument but is otherwise ignored. */ |
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) | if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) |
{ |
{ |
if ((cxt & NUM_SAWDIGITS) == 0) |
if ((cxt & NUM_SAWDIGITS) == 0) |
{ |
{ |
Line 142 _rl_arg_dispatch (cxt, c)
|
Line 138 _rl_arg_dispatch (cxt, c)
|
} |
} |
else |
else |
{ |
{ |
RL_SETSTATE(RL_STATE_MOREINPUT); | key = _rl_bracketed_read_key (); |
key = rl_read_key (); | |
RL_UNSETSTATE(RL_STATE_MOREINPUT); | |
rl_restore_prompt (); |
rl_restore_prompt (); |
rl_clear_message (); |
rl_clear_message (); |
RL_UNSETSTATE(RL_STATE_NUMERICARG); |
RL_UNSETSTATE(RL_STATE_NUMERICARG); |
Line 195 _rl_arg_dispatch (cxt, c)
|
Line 189 _rl_arg_dispatch (cxt, c)
|
|
|
/* Handle C-u style numeric args, as well as M--, and M-digits. */ |
/* Handle C-u style numeric args, as well as M--, and M-digits. */ |
static int |
static int |
rl_digit_loop () | rl_digit_loop (void) |
{ |
{ |
int c, r; |
int c, r; |
|
|
Line 222 rl_digit_loop ()
|
Line 216 rl_digit_loop ()
|
|
|
/* Create a default argument. */ |
/* Create a default argument. */ |
void |
void |
_rl_reset_argument () | _rl_reset_argument (void) |
{ |
{ |
rl_numeric_arg = rl_arg_sign = 1; |
rl_numeric_arg = rl_arg_sign = 1; |
rl_explicit_arg = 0; |
rl_explicit_arg = 0; |
Line 231 _rl_reset_argument ()
|
Line 225 _rl_reset_argument ()
|
|
|
/* Start a numeric argument with initial value KEY */ |
/* Start a numeric argument with initial value KEY */ |
int |
int |
rl_digit_argument (ignore, key) | rl_digit_argument (int ignore, int key) |
int ignore, key; | |
{ |
{ |
_rl_arg_init (); |
_rl_arg_init (); |
if (RL_ISSTATE (RL_STATE_CALLBACK)) |
if (RL_ISSTATE (RL_STATE_CALLBACK)) |
Line 252 rl_digit_argument (ignore, key)
|
Line 245 rl_digit_argument (ignore, key)
|
Read a key. If the key has nothing to do with arguments, then |
Read a key. If the key has nothing to do with arguments, then |
dispatch on it. If the key is the abort character then abort. */ |
dispatch on it. If the key is the abort character then abort. */ |
int |
int |
rl_universal_argument (count, key) | rl_universal_argument (int count, int key) |
int count, key; | |
{ |
{ |
_rl_arg_init (); |
_rl_arg_init (); |
rl_numeric_arg *= 4; |
rl_numeric_arg *= 4; |
Line 262 rl_universal_argument (count, key)
|
Line 254 rl_universal_argument (count, key)
|
} |
} |
|
|
int |
int |
_rl_arg_callback (cxt) | _rl_arg_callback (_rl_arg_cxt cxt) |
_rl_arg_cxt cxt; | |
{ |
{ |
int c, r; |
int c, r; |
|
|
c = _rl_arg_getchar (); |
c = _rl_arg_getchar (); |
|
if (c < 0) |
|
return (1); /* EOF */ |
|
|
if (_rl_argcxt & NUM_READONE) |
if (_rl_argcxt & NUM_READONE) |
{ |
{ |
Line 280 _rl_arg_callback (cxt)
|
Line 273 _rl_arg_callback (cxt)
|
} |
} |
|
|
r = _rl_arg_dispatch (cxt, c); |
r = _rl_arg_dispatch (cxt, c); |
|
if (r > 0) |
|
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); |
return (r != 1); |
return (r != 1); |
} |
} |
|
|
/* What to do when you abort reading an argument. */ |
/* What to do when you abort reading an argument. */ |
int |
int |
rl_discard_argument () | rl_discard_argument (void) |
{ |
{ |
rl_ding (); |
rl_ding (); |
rl_clear_message (); |
rl_clear_message (); |
Line 310 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *
|
Line 305 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *
|
|
|
/* Set the history pointer back to the last entry in the history. */ |
/* Set the history pointer back to the last entry in the history. */ |
void |
void |
_rl_start_using_history () | _rl_start_using_history (void) |
{ |
{ |
using_history (); |
using_history (); |
if (_rl_saved_line_for_history) |
if (_rl_saved_line_for_history) |
Line 321 _rl_start_using_history ()
|
Line 316 _rl_start_using_history ()
|
|
|
/* Free the contents (and containing structure) of a HIST_ENTRY. */ |
/* Free the contents (and containing structure) of a HIST_ENTRY. */ |
void |
void |
_rl_free_history_entry (entry) | _rl_free_history_entry (HIST_ENTRY *entry) |
HIST_ENTRY *entry; | |
{ |
{ |
if (entry == 0) |
if (entry == 0) |
return; |
return; |
Line 335 _rl_free_history_entry (entry)
|
Line 329 _rl_free_history_entry (entry)
|
|
|
/* Perhaps put back the current line if it has changed. */ |
/* Perhaps put back the current line if it has changed. */ |
int |
int |
rl_maybe_replace_line () | rl_maybe_replace_line (void) |
{ |
{ |
HIST_ENTRY *temp; |
HIST_ENTRY *temp; |
|
|
Line 353 rl_maybe_replace_line ()
|
Line 347 rl_maybe_replace_line ()
|
|
|
/* Restore the _rl_saved_line_for_history if there is one. */ |
/* Restore the _rl_saved_line_for_history if there is one. */ |
int |
int |
rl_maybe_unsave_line () | rl_maybe_unsave_line (void) |
{ |
{ |
if (_rl_saved_line_for_history) |
if (_rl_saved_line_for_history) |
{ |
{ |
Line 372 rl_maybe_unsave_line ()
|
Line 366 rl_maybe_unsave_line ()
|
|
|
/* Save the current line in _rl_saved_line_for_history. */ |
/* Save the current line in _rl_saved_line_for_history. */ |
int |
int |
rl_maybe_save_line () | rl_maybe_save_line (void) |
{ |
{ |
if (_rl_saved_line_for_history == 0) |
if (_rl_saved_line_for_history == 0) |
{ |
{ |
Line 386 rl_maybe_save_line ()
|
Line 380 rl_maybe_save_line ()
|
} |
} |
|
|
int |
int |
_rl_free_saved_history_line () | _rl_free_saved_history_line (void) |
{ |
{ |
if (_rl_saved_line_for_history) |
if (_rl_saved_line_for_history) |
{ |
{ |
Line 397 _rl_free_saved_history_line ()
|
Line 391 _rl_free_saved_history_line ()
|
} |
} |
|
|
static void |
static void |
_rl_history_set_point () | _rl_history_set_point (void) |
{ |
{ |
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) |
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) |
? _rl_history_saved_point |
? _rl_history_saved_point |
Line 415 _rl_history_set_point ()
|
Line 409 _rl_history_set_point ()
|
} |
} |
|
|
void |
void |
rl_replace_from_history (entry, flags) | rl_replace_from_history (HIST_ENTRY *entry, int flags) |
HIST_ENTRY *entry; | |
int flags; /* currently unused */ | |
{ |
{ |
/* Can't call with `1' because rl_undo_list might point to an undo list |
/* Can't call with `1' because rl_undo_list might point to an undo list |
from a history entry, just like we're setting up here. */ |
from a history entry, just like we're setting up here. */ |
Line 441 rl_replace_from_history (entry, flags)
|
Line 433 rl_replace_from_history (entry, flags)
|
intended to be called while actively editing, and the current line is |
intended to be called while actively editing, and the current line is |
not assumed to have been added to the history list. */ |
not assumed to have been added to the history list. */ |
void |
void |
_rl_revert_all_lines () | _rl_revert_previous_lines (void) |
{ |
{ |
int hpos; |
int hpos; |
HIST_ENTRY *entry; |
HIST_ENTRY *entry; |
Line 485 _rl_revert_all_lines ()
|
Line 477 _rl_revert_all_lines ()
|
xfree (lbuf); |
xfree (lbuf); |
} |
} |
|
|
|
/* Revert all lines in the history by making sure we are at the end of the |
|
history before calling _rl_revert_previous_lines() */ |
|
void |
|
_rl_revert_all_lines (void) |
|
{ |
|
int pos; |
|
|
|
pos = where_history (); |
|
using_history (); |
|
_rl_revert_previous_lines (); |
|
history_set_pos (pos); |
|
} |
|
|
/* Free the history list, including private readline data and take care |
/* Free the history list, including private readline data and take care |
of pointer aliases to history data. Resets rl_undo_list if it points |
of pointer aliases to history data. Resets rl_undo_list if it points |
to an UNDO_LIST * saved as some history entry's data member. This |
to an UNDO_LIST * saved as some history entry's data member. This |
should not be called while editing is active. */ |
should not be called while editing is active. */ |
void |
void |
rl_clear_history () | rl_clear_history (void) |
{ |
{ |
HIST_ENTRY **hlist, *hent; |
HIST_ENTRY **hlist, *hent; |
register int i; |
register int i; |
Line 524 rl_clear_history ()
|
Line 529 rl_clear_history ()
|
|
|
/* Meta-< goes to the start of the history. */ |
/* Meta-< goes to the start of the history. */ |
int |
int |
rl_beginning_of_history (count, key) | rl_beginning_of_history (int count, int key) |
int count, key; | |
{ |
{ |
return (rl_get_previous_history (1 + where_history (), key)); |
return (rl_get_previous_history (1 + where_history (), key)); |
} |
} |
|
|
/* Meta-> goes to the end of the history. (The current line). */ |
/* Meta-> goes to the end of the history. (The current line). */ |
int |
int |
rl_end_of_history (count, key) | rl_end_of_history (int count, int key) |
int count, key; | |
{ |
{ |
rl_maybe_replace_line (); |
rl_maybe_replace_line (); |
using_history (); |
using_history (); |
Line 543 rl_end_of_history (count, key)
|
Line 546 rl_end_of_history (count, key)
|
|
|
/* Move down to the next history line. */ |
/* Move down to the next history line. */ |
int |
int |
rl_get_next_history (count, key) | rl_get_next_history (int count, int key) |
int count, key; | |
{ |
{ |
HIST_ENTRY *temp; |
HIST_ENTRY *temp; |
|
|
Line 582 rl_get_next_history (count, key)
|
Line 584 rl_get_next_history (count, key)
|
/* Get the previous item out of our interactive history, making it the current |
/* Get the previous item out of our interactive history, making it the current |
line. If there is no previous history, just ding. */ |
line. If there is no previous history, just ding. */ |
int |
int |
rl_get_previous_history (count, key) | rl_get_previous_history (int count, int key) |
int count, key; | |
{ |
{ |
HIST_ENTRY *old_temp, *temp; |
HIST_ENTRY *old_temp, *temp; |
|
int had_saved_line; |
|
|
if (count < 0) |
if (count < 0) |
return (rl_get_next_history (-count, key)); |
return (rl_get_next_history (-count, key)); |
|
|
if (count == 0) | if (count == 0 || history_list () == 0) |
return 0; |
return 0; |
|
|
/* either not saved by rl_newline or at end of line, so set appropriately. */ |
/* either not saved by rl_newline or at end of line, so set appropriately. */ |
Line 598 rl_get_previous_history (count, key)
|
Line 600 rl_get_previous_history (count, key)
|
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; |
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; |
|
|
/* If we don't have a line saved, then save this one. */ |
/* 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 (); |
rl_maybe_save_line (); |
|
|
/* If the current line has changed, save the changes. */ |
/* If the current line has changed, save the changes. */ |
Line 620 rl_get_previous_history (count, key)
|
Line 623 rl_get_previous_history (count, key)
|
temp = old_temp; |
temp = old_temp; |
|
|
if (temp == 0) |
if (temp == 0) |
rl_ding (); | { |
| if (had_saved_line == 0) |
| _rl_free_saved_history_line (); |
| rl_ding (); |
| } |
else |
else |
{ |
{ |
rl_replace_from_history (temp, 0); |
rl_replace_from_history (temp, 0); |
Line 630 rl_get_previous_history (count, key)
|
Line 637 rl_get_previous_history (count, key)
|
return 0; |
return 0; |
} |
} |
|
|
|
/* The equivalent of the Korn shell C-o operate-and-get-next-history-line |
|
editing command. */ |
|
|
|
/* This could stand to be global to the readline library */ |
|
static rl_hook_func_t *_rl_saved_internal_startup_hook = 0; |
|
static int saved_history_logical_offset = -1; |
|
|
|
#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries) |
|
|
|
static int |
|
set_saved_history () |
|
{ |
|
int absolute_offset, count; |
|
|
|
if (saved_history_logical_offset >= 0) |
|
{ |
|
absolute_offset = saved_history_logical_offset - history_base; |
|
count = where_history () - absolute_offset; |
|
rl_get_previous_history (count, 0); |
|
} |
|
saved_history_logical_offset = -1; |
|
_rl_internal_startup_hook = _rl_saved_internal_startup_hook; |
|
|
|
return (0); |
|
} |
|
|
|
int |
|
rl_operate_and_get_next (count, c) |
|
int count, c; |
|
{ |
|
/* Accept the current line. */ |
|
rl_newline (1, c); |
|
|
|
saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1; |
|
|
|
|
|
_rl_saved_internal_startup_hook = _rl_internal_startup_hook; |
|
_rl_internal_startup_hook = set_saved_history; |
|
|
|
return 0; |
|
} |
|
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* */ |
/* */ |
/* Editing Modes */ |
/* Editing Modes */ |
Line 637 rl_get_previous_history (count, key)
|
Line 686 rl_get_previous_history (count, key)
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* How to toggle back and forth between editing modes. */ |
/* How to toggle back and forth between editing modes. */ |
int |
int |
rl_vi_editing_mode (count, key) | rl_vi_editing_mode (int count, int key) |
int count, key; | |
{ |
{ |
#if defined (VI_MODE) |
#if defined (VI_MODE) |
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ |
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ |
Line 650 rl_vi_editing_mode (count, key)
|
Line 698 rl_vi_editing_mode (count, key)
|
} |
} |
|
|
int |
int |
rl_emacs_editing_mode (count, key) | rl_emacs_editing_mode (int count, int key) |
int count, key; | |
{ |
{ |
rl_editing_mode = emacs_mode; |
rl_editing_mode = emacs_mode; |
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ |
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ |
Line 665 rl_emacs_editing_mode (count, key)
|
Line 712 rl_emacs_editing_mode (count, key)
|
|
|
/* Function for the rest of the library to use to set insert/overwrite mode. */ |
/* Function for the rest of the library to use to set insert/overwrite mode. */ |
void |
void |
_rl_set_insert_mode (im, force) | _rl_set_insert_mode (int im, int force) |
int im, force; | |
{ |
{ |
#ifdef CURSOR_MODE |
#ifdef CURSOR_MODE |
_rl_set_cursor (im, force); |
_rl_set_cursor (im, force); |
Line 678 _rl_set_insert_mode (im, force)
|
Line 724 _rl_set_insert_mode (im, force)
|
/* Toggle overwrite mode. A positive explicit argument selects overwrite |
/* Toggle overwrite mode. A positive explicit argument selects overwrite |
mode. A negative or zero explicit argument selects insert mode. */ |
mode. A negative or zero explicit argument selects insert mode. */ |
int |
int |
rl_overwrite_mode (count, key) | rl_overwrite_mode (int count, int key) |
int count, key; | |
{ |
{ |
if (rl_explicit_arg == 0) |
if (rl_explicit_arg == 0) |
_rl_set_insert_mode (rl_insert_mode ^ 1, 0); |
_rl_set_insert_mode (rl_insert_mode ^ 1, 0); |