1 /* misc.c -- miscellaneous bindable readline functions. */
3 /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
22 #define READLINE_LIBRARY
24 #if defined (HAVE_CONFIG_H)
28 #if defined (HAVE_UNISTD_H)
30 #endif /* HAVE_UNISTD_H */
32 #if defined (HAVE_STDLIB_H)
35 # include "ansi_stdlib.h"
36 #endif /* HAVE_STDLIB_H */
38 #if defined (HAVE_LOCALE_H)
44 /* System-specific feature definitions and include files. */
48 /* Some standard library routines. */
52 #include "rlprivate.h"
56 static int rl_digit_loop PARAMS((void));
57 static void _rl_history_set_point PARAMS((void));
59 /* Forward declarations used in this file */
60 void _rl_free_history_entry PARAMS((HIST_ENTRY *));
62 /* If non-zero, rl_get_previous_history and rl_get_next_history attempt
63 to preserve the value of rl_point from line to line. */
64 int _rl_history_preserve_point = 0;
66 _rl_arg_cxt _rl_argcxt;
68 /* Saved target point for when _rl_history_preserve_point is set. Special
69 value of -1 means that point is at the end of the line. */
70 int _rl_history_saved_point = -1;
72 /* **************************************************************** */
74 /* Numeric Arguments */
76 /* **************************************************************** */
79 _rl_arg_overflow (void)
81 if (rl_numeric_arg > 1000000)
84 rl_explicit_arg = rl_numeric_arg = 0;
88 RL_UNSETSTATE(RL_STATE_NUMERICARG);
99 RL_SETSTATE(RL_STATE_NUMERICARG);
103 _rl_arg_getchar (void)
107 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
108 RL_SETSTATE(RL_STATE_MOREINPUT);
110 RL_UNSETSTATE(RL_STATE_MOREINPUT);
115 /* Process C as part of the current numeric argument. Return -1 if the
116 argument should be aborted, 0 if we should not read any more chars, and
117 1 if we should continue to read chars. */
119 _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
125 /* If we see a key bound to `universal-argument' after seeing digits,
126 it ends the argument but is otherwise ignored. */
127 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
129 if ((cxt & NUM_SAWDIGITS) == 0)
134 else if (RL_ISSTATE (RL_STATE_CALLBACK))
136 _rl_argcxt |= NUM_READONE;
141 RL_SETSTATE(RL_STATE_MOREINPUT);
142 key = rl_read_key ();
143 RL_UNSETSTATE(RL_STATE_MOREINPUT);
144 rl_restore_prompt ();
146 RL_UNSETSTATE(RL_STATE_NUMERICARG);
149 return (_rl_dispatch (key, _rl_keymap));
157 r = _rl_digit_value (c);
158 rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
160 _rl_argcxt |= NUM_SAWDIGITS;
162 else if (c == '-' && rl_explicit_arg == 0)
165 _rl_argcxt |= NUM_SAWMINUS;
170 /* Make M-- command equivalent to M--1 command. */
171 if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
173 rl_restore_prompt ();
175 RL_UNSETSTATE(RL_STATE_NUMERICARG);
177 r = _rl_dispatch (key, _rl_keymap);
178 if (RL_ISSTATE (RL_STATE_CALLBACK))
180 /* At worst, this will cause an extra redisplay. Otherwise,
181 we have to wait until the next character comes in. */
183 (*rl_redisplay_function) ();
192 /* Handle C-u style numeric args, as well as M--, and M-digits. */
200 if (_rl_arg_overflow ())
203 c = _rl_arg_getchar ();
207 _rl_abort_internal ();
211 r = _rl_arg_dispatch (_rl_argcxt, c);
212 if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
219 /* Create a default argument. */
221 _rl_reset_argument (void)
223 rl_numeric_arg = rl_arg_sign = 1;
228 /* Start a numeric argument with initial value KEY */
230 rl_digit_argument (int ignore, int key)
233 if (RL_ISSTATE (RL_STATE_CALLBACK))
235 _rl_arg_dispatch (_rl_argcxt, key);
236 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
241 rl_execute_next (key);
242 return (rl_digit_loop ());
246 /* C-u, universal argument. Multiply the current argument by 4.
247 Read a key. If the key has nothing to do with arguments, then
248 dispatch on it. If the key is the abort character then abort. */
250 rl_universal_argument (int count, int key)
255 return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
259 _rl_arg_callback (_rl_arg_cxt cxt)
263 c = _rl_arg_getchar ();
265 return (1); /* EOF */
267 if (_rl_argcxt & NUM_READONE)
269 _rl_argcxt &= ~NUM_READONE;
270 rl_restore_prompt ();
272 RL_UNSETSTATE(RL_STATE_NUMERICARG);
277 r = _rl_arg_dispatch (cxt, c);
279 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
283 /* What to do when you abort reading an argument. */
285 rl_discard_argument (void)
289 _rl_reset_argument ();
294 /* **************************************************************** */
296 /* History Utilities */
298 /* **************************************************************** */
300 /* We already have a history library, and that is what we use to control
301 the history features of readline. This is our local interface to
302 the history mechanism. */
304 /* While we are editing the history, this is the saved
305 version of the original line. */
306 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
308 /* Set the history pointer back to the last entry in the history. */
310 _rl_start_using_history (void)
313 if (_rl_saved_line_for_history)
314 _rl_free_history_entry (_rl_saved_line_for_history);
316 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
319 /* Free the contents (and containing structure) of a HIST_ENTRY. */
321 _rl_free_history_entry (HIST_ENTRY *entry)
327 FREE (entry->timestamp);
332 /* Perhaps put back the current line if it has changed. */
334 rl_maybe_replace_line (void)
338 temp = current_history ();
339 /* If the current line has changed, save the changes. */
340 if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
342 temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
344 FREE (temp->timestamp);
350 /* Restore the _rl_saved_line_for_history if there is one. */
352 rl_maybe_unsave_line (void)
354 if (_rl_saved_line_for_history)
356 /* Can't call with `1' because rl_undo_list might point to an undo
357 list from a history entry, as in rl_replace_from_history() below. */
358 rl_replace_line (_rl_saved_line_for_history->line, 0);
359 rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
360 _rl_free_history_entry (_rl_saved_line_for_history);
361 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
362 rl_point = rl_end; /* rl_replace_line sets rl_end */
369 /* Save the current line in _rl_saved_line_for_history. */
371 rl_maybe_save_line (void)
373 if (_rl_saved_line_for_history == 0)
375 _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
376 _rl_saved_line_for_history->line = savestring (rl_line_buffer);
377 _rl_saved_line_for_history->timestamp = (char *)NULL;
378 _rl_saved_line_for_history->data = (char *)rl_undo_list;
385 _rl_free_saved_history_line (void)
387 if (_rl_saved_line_for_history)
389 _rl_free_history_entry (_rl_saved_line_for_history);
390 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
396 _rl_history_set_point (void)
398 rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
399 ? _rl_history_saved_point
401 if (rl_point > rl_end)
404 #if defined (VI_MODE)
405 if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
409 if (rl_editing_mode == emacs_mode)
410 rl_mark = (rl_point == rl_end ? 0 : rl_end);
414 rl_replace_from_history (HIST_ENTRY *entry, int flags)
416 /* Can't call with `1' because rl_undo_list might point to an undo list
417 from a history entry, just like we're setting up here. */
418 rl_replace_line (entry->line, 0);
419 rl_undo_list = (UNDO_LIST *)entry->data;
423 #if defined (VI_MODE)
424 if (rl_editing_mode == vi_mode)
432 /* Process and free undo lists attached to each history entry prior to the
433 current entry, inclusive, reverting each line to its saved state. This
434 is destructive, and state about the current line is lost. This is not
435 intended to be called while actively editing, and the current line is
436 not assumed to have been added to the history list. */
438 _rl_revert_all_lines (void)
442 UNDO_LIST *ul, *saved_undo_list;
445 lbuf = savestring (rl_line_buffer);
446 saved_undo_list = rl_undo_list;
447 hpos = where_history ();
449 entry = (hpos == history_length) ? previous_history () : current_history ();
452 if (ul = (UNDO_LIST *)entry->data)
454 if (ul == saved_undo_list)
456 /* Set up rl_line_buffer and other variables from history entry */
457 rl_replace_from_history (entry, 0); /* entry->line is now current */
458 entry->data = 0; /* entry->data is now current undo list */
459 /* Undo all changes to this history entry */
462 /* And copy the reverted line back to the history entry, preserving
465 entry->line = savestring (rl_line_buffer);
467 entry = previous_history ();
470 /* Restore history state */
471 rl_undo_list = saved_undo_list; /* may have been set to null */
472 history_set_pos (hpos);
474 /* reset the line buffer */
475 rl_replace_line (lbuf, 0);
482 /* Free the history list, including private readline data and take care
483 of pointer aliases to history data. Resets rl_undo_list if it points
484 to an UNDO_LIST * saved as some history entry's data member. This
485 should not be called while editing is active. */
487 rl_clear_history (void)
489 HIST_ENTRY **hlist, *hent;
491 UNDO_LIST *ul, *saved_undo_list;
493 saved_undo_list = rl_undo_list;
494 hlist = history_list (); /* direct pointer, not copy */
496 for (i = 0; i < history_length; i++)
499 if (ul = (UNDO_LIST *)hent->data)
501 if (ul == saved_undo_list)
503 _rl_free_undo_list (ul);
506 _rl_free_history_entry (hent);
509 history_offset = history_length = 0;
510 rl_undo_list = saved_undo_list; /* should be NULL */
513 /* **************************************************************** */
515 /* History Commands */
517 /* **************************************************************** */
519 /* Meta-< goes to the start of the history. */
521 rl_beginning_of_history (int count, int key)
523 return (rl_get_previous_history (1 + where_history (), key));
526 /* Meta-> goes to the end of the history. (The current line). */
528 rl_end_of_history (int count, int key)
530 rl_maybe_replace_line ();
532 rl_maybe_unsave_line ();
536 /* Move down to the next history line. */
538 rl_get_next_history (int count, int key)
543 return (rl_get_previous_history (-count, key));
548 rl_maybe_replace_line ();
550 /* either not saved by rl_newline or at end of line, so set appropriately. */
551 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
552 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
554 temp = (HIST_ENTRY *)NULL;
557 temp = next_history ();
564 rl_maybe_unsave_line ();
567 rl_replace_from_history (temp, 0);
568 _rl_history_set_point ();
573 /* Get the previous item out of our interactive history, making it the current
574 line. If there is no previous history, just ding. */
576 rl_get_previous_history (int count, int key)
578 HIST_ENTRY *old_temp, *temp;
581 return (rl_get_next_history (-count, key));
583 if (count == 0 || history_list () == 0)
586 /* either not saved by rl_newline or at end of line, so set appropriately. */
587 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
588 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
590 /* If we don't have a line saved, then save this one. */
591 rl_maybe_save_line ();
593 /* If the current line has changed, save the changes. */
594 rl_maybe_replace_line ();
596 temp = old_temp = (HIST_ENTRY *)NULL;
599 temp = previous_history ();
607 /* If there was a large argument, and we moved back to the start of the
608 history, that is not an error. So use the last value found. */
609 if (!temp && old_temp)
614 rl_maybe_unsave_line ();
619 rl_replace_from_history (temp, 0);
620 _rl_history_set_point ();
626 /* **************************************************************** */
630 /* **************************************************************** */
631 /* How to toggle back and forth between editing modes. */
633 rl_vi_editing_mode (int count, int key)
635 #if defined (VI_MODE)
636 _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
637 rl_editing_mode = vi_mode;
638 rl_vi_insert_mode (1, key);
645 rl_emacs_editing_mode (int count, int key)
647 rl_editing_mode = emacs_mode;
648 _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
649 _rl_keymap = emacs_standard_keymap;
651 if (_rl_show_mode_in_prompt)
657 /* Function for the rest of the library to use to set insert/overwrite mode. */
659 _rl_set_insert_mode (int im, int force)
662 _rl_set_cursor (im, force);
668 /* Toggle overwrite mode. A positive explicit argument selects overwrite
669 mode. A negative or zero explicit argument selects insert mode. */
671 rl_overwrite_mode (int count, int key)
673 if (rl_explicit_arg == 0)
674 _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
676 _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
678 _rl_set_insert_mode (RL_IM_INSERT, 0);