1 /* misc.c -- miscellaneous bindable readline functions. */
3 /* Copyright (C) 1987-2015 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 /* **************************************************************** */
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);
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 (cxt, c)
127 /* If we see a key bound to `universal-argument' after seeing digits,
128 it ends the argument but is otherwise ignored. */
129 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
131 if ((cxt & NUM_SAWDIGITS) == 0)
136 else if (RL_ISSTATE (RL_STATE_CALLBACK))
138 _rl_argcxt |= NUM_READONE;
143 RL_SETSTATE(RL_STATE_MOREINPUT);
144 key = rl_read_key ();
145 RL_UNSETSTATE(RL_STATE_MOREINPUT);
146 rl_restore_prompt ();
148 RL_UNSETSTATE(RL_STATE_NUMERICARG);
151 return (_rl_dispatch (key, _rl_keymap));
159 r = _rl_digit_value (c);
160 rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
162 _rl_argcxt |= NUM_SAWDIGITS;
164 else if (c == '-' && rl_explicit_arg == 0)
167 _rl_argcxt |= NUM_SAWMINUS;
172 /* Make M-- command equivalent to M--1 command. */
173 if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
175 rl_restore_prompt ();
177 RL_UNSETSTATE(RL_STATE_NUMERICARG);
179 r = _rl_dispatch (key, _rl_keymap);
180 if (RL_ISSTATE (RL_STATE_CALLBACK))
182 /* At worst, this will cause an extra redisplay. Otherwise,
183 we have to wait until the next character comes in. */
185 (*rl_redisplay_function) ();
194 /* Handle C-u style numeric args, as well as M--, and M-digits. */
202 if (_rl_arg_overflow ())
205 c = _rl_arg_getchar ();
209 _rl_abort_internal ();
213 r = _rl_arg_dispatch (_rl_argcxt, c);
214 if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
221 /* Create a default argument. */
223 _rl_reset_argument ()
225 rl_numeric_arg = rl_arg_sign = 1;
230 /* Start a numeric argument with initial value KEY */
232 rl_digit_argument (ignore, key)
236 if (RL_ISSTATE (RL_STATE_CALLBACK))
238 _rl_arg_dispatch (_rl_argcxt, key);
239 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
244 rl_execute_next (key);
245 return (rl_digit_loop ());
249 /* C-u, universal argument. Multiply the current argument by 4.
250 Read a key. If the key has nothing to do with arguments, then
251 dispatch on it. If the key is the abort character then abort. */
253 rl_universal_argument (count, key)
259 return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
263 _rl_arg_callback (cxt)
268 c = _rl_arg_getchar ();
270 return (1); /* EOF */
272 if (_rl_argcxt & NUM_READONE)
274 _rl_argcxt &= ~NUM_READONE;
275 rl_restore_prompt ();
277 RL_UNSETSTATE(RL_STATE_NUMERICARG);
282 r = _rl_arg_dispatch (cxt, c);
286 /* What to do when you abort reading an argument. */
288 rl_discard_argument ()
292 _rl_reset_argument ();
297 /* **************************************************************** */
299 /* History Utilities */
301 /* **************************************************************** */
303 /* We already have a history library, and that is what we use to control
304 the history features of readline. This is our local interface to
305 the history mechanism. */
307 /* While we are editing the history, this is the saved
308 version of the original line. */
309 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
311 /* Set the history pointer back to the last entry in the history. */
313 _rl_start_using_history ()
316 if (_rl_saved_line_for_history)
317 _rl_free_history_entry (_rl_saved_line_for_history);
319 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
322 /* Free the contents (and containing structure) of a HIST_ENTRY. */
324 _rl_free_history_entry (entry)
331 FREE (entry->timestamp);
336 /* Perhaps put back the current line if it has changed. */
338 rl_maybe_replace_line ()
342 temp = current_history ();
343 /* If the current line has changed, save the changes. */
344 if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
346 temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
348 FREE (temp->timestamp);
354 /* Restore the _rl_saved_line_for_history if there is one. */
356 rl_maybe_unsave_line ()
358 if (_rl_saved_line_for_history)
360 /* Can't call with `1' because rl_undo_list might point to an undo
361 list from a history entry, as in rl_replace_from_history() below. */
362 rl_replace_line (_rl_saved_line_for_history->line, 0);
363 rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
364 _rl_free_history_entry (_rl_saved_line_for_history);
365 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
366 rl_point = rl_end; /* rl_replace_line sets rl_end */
373 /* Save the current line in _rl_saved_line_for_history. */
375 rl_maybe_save_line ()
377 if (_rl_saved_line_for_history == 0)
379 _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
380 _rl_saved_line_for_history->line = savestring (rl_line_buffer);
381 _rl_saved_line_for_history->timestamp = (char *)NULL;
382 _rl_saved_line_for_history->data = (char *)rl_undo_list;
389 _rl_free_saved_history_line ()
391 if (_rl_saved_line_for_history)
393 _rl_free_history_entry (_rl_saved_line_for_history);
394 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
400 _rl_history_set_point ()
402 rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
403 ? _rl_history_saved_point
405 if (rl_point > rl_end)
408 #if defined (VI_MODE)
409 if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
413 if (rl_editing_mode == emacs_mode)
414 rl_mark = (rl_point == rl_end ? 0 : rl_end);
418 rl_replace_from_history (entry, flags)
420 int flags; /* currently unused */
422 /* Can't call with `1' because rl_undo_list might point to an undo list
423 from a history entry, just like we're setting up here. */
424 rl_replace_line (entry->line, 0);
425 rl_undo_list = (UNDO_LIST *)entry->data;
429 #if defined (VI_MODE)
430 if (rl_editing_mode == vi_mode)
438 /* Process and free undo lists attached to each history entry prior to the
439 current entry, inclusive, reverting each line to its saved state. This
440 is destructive, and state about the current line is lost. This is not
441 intended to be called while actively editing, and the current line is
442 not assumed to have been added to the history list. */
444 _rl_revert_all_lines ()
448 UNDO_LIST *ul, *saved_undo_list;
451 lbuf = savestring (rl_line_buffer);
452 saved_undo_list = rl_undo_list;
453 hpos = where_history ();
455 entry = (hpos == history_length) ? previous_history () : current_history ();
458 if (ul = (UNDO_LIST *)entry->data)
460 if (ul == saved_undo_list)
462 /* Set up rl_line_buffer and other variables from history entry */
463 rl_replace_from_history (entry, 0); /* entry->line is now current */
464 entry->data = 0; /* entry->data is now current undo list */
465 /* Undo all changes to this history entry */
468 /* And copy the reverted line back to the history entry, preserving
471 entry->line = savestring (rl_line_buffer);
473 entry = previous_history ();
476 /* Restore history state */
477 rl_undo_list = saved_undo_list; /* may have been set to null */
478 history_set_pos (hpos);
480 /* reset the line buffer */
481 rl_replace_line (lbuf, 0);
488 /* Free the history list, including private readline data and take care
489 of pointer aliases to history data. Resets rl_undo_list if it points
490 to an UNDO_LIST * saved as some history entry's data member. This
491 should not be called while editing is active. */
495 HIST_ENTRY **hlist, *hent;
497 UNDO_LIST *ul, *saved_undo_list;
499 saved_undo_list = rl_undo_list;
500 hlist = history_list (); /* direct pointer, not copy */
502 for (i = 0; i < history_length; i++)
505 if (ul = (UNDO_LIST *)hent->data)
507 if (ul == saved_undo_list)
509 _rl_free_undo_list (ul);
512 _rl_free_history_entry (hent);
515 history_offset = history_length = 0;
516 rl_undo_list = saved_undo_list; /* should be NULL */
519 /* **************************************************************** */
521 /* History Commands */
523 /* **************************************************************** */
525 /* Meta-< goes to the start of the history. */
527 rl_beginning_of_history (count, key)
530 return (rl_get_previous_history (1 + where_history (), key));
533 /* Meta-> goes to the end of the history. (The current line). */
535 rl_end_of_history (count, key)
538 rl_maybe_replace_line ();
540 rl_maybe_unsave_line ();
544 /* Move down to the next history line. */
546 rl_get_next_history (count, key)
552 return (rl_get_previous_history (-count, key));
557 rl_maybe_replace_line ();
559 /* either not saved by rl_newline or at end of line, so set appropriately. */
560 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
561 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
563 temp = (HIST_ENTRY *)NULL;
566 temp = next_history ();
573 rl_maybe_unsave_line ();
576 rl_replace_from_history (temp, 0);
577 _rl_history_set_point ();
582 /* Get the previous item out of our interactive history, making it the current
583 line. If there is no previous history, just ding. */
585 rl_get_previous_history (count, key)
588 HIST_ENTRY *old_temp, *temp;
591 return (rl_get_next_history (-count, key));
596 /* either not saved by rl_newline or at end of line, so set appropriately. */
597 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
598 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
600 /* If we don't have a line saved, then save this one. */
601 rl_maybe_save_line ();
603 /* If the current line has changed, save the changes. */
604 rl_maybe_replace_line ();
606 temp = old_temp = (HIST_ENTRY *)NULL;
609 temp = previous_history ();
617 /* If there was a large argument, and we moved back to the start of the
618 history, that is not an error. So use the last value found. */
619 if (!temp && old_temp)
626 rl_replace_from_history (temp, 0);
627 _rl_history_set_point ();
633 /* **************************************************************** */
637 /* **************************************************************** */
638 /* How to toggle back and forth between editing modes. */
640 rl_vi_editing_mode (count, key)
643 #if defined (VI_MODE)
644 _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
645 rl_editing_mode = vi_mode;
646 rl_vi_insert_mode (1, key);
653 rl_emacs_editing_mode (count, key)
656 rl_editing_mode = emacs_mode;
657 _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
658 _rl_keymap = emacs_standard_keymap;
660 if (_rl_show_mode_in_prompt)
666 /* Function for the rest of the library to use to set insert/overwrite mode. */
668 _rl_set_insert_mode (im, force)
672 _rl_set_cursor (im, force);
678 /* Toggle overwrite mode. A positive explicit argument selects overwrite
679 mode. A negative or zero explicit argument selects insert mode. */
681 rl_overwrite_mode (count, key)
684 if (rl_explicit_arg == 0)
685 _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
687 _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
689 _rl_set_insert_mode (RL_IM_INSERT, 0);