1 /* misc.c -- miscellaneous bindable readline functions. */
3 /* Copyright (C) 1987-2019 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 key
= _rl_bracketed_read_key ();
142 rl_restore_prompt ();
144 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
147 return (_rl_dispatch (key
, _rl_keymap
));
155 r
= _rl_digit_value (c
);
156 rl_numeric_arg
= rl_explicit_arg
? (rl_numeric_arg
* 10) + r
: r
;
158 _rl_argcxt
|= NUM_SAWDIGITS
;
160 else if (c
== '-' && rl_explicit_arg
== 0)
163 _rl_argcxt
|= NUM_SAWMINUS
;
168 /* Make M-- command equivalent to M--1 command. */
169 if ((_rl_argcxt
& NUM_SAWMINUS
) && rl_numeric_arg
== 1 && rl_explicit_arg
== 0)
171 rl_restore_prompt ();
173 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
175 r
= _rl_dispatch (key
, _rl_keymap
);
176 if (RL_ISSTATE (RL_STATE_CALLBACK
))
178 /* At worst, this will cause an extra redisplay. Otherwise,
179 we have to wait until the next character comes in. */
181 (*rl_redisplay_function
) ();
190 /* Handle C-u style numeric args, as well as M--, and M-digits. */
198 if (_rl_arg_overflow ())
201 c
= _rl_arg_getchar ();
205 _rl_abort_internal ();
209 r
= _rl_arg_dispatch (_rl_argcxt
, c
);
210 if (r
<= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG
) == 0))
217 /* Create a default argument. */
219 _rl_reset_argument (void)
221 rl_numeric_arg
= rl_arg_sign
= 1;
226 /* Start a numeric argument with initial value KEY */
228 rl_digit_argument (int ignore
, int key
)
231 if (RL_ISSTATE (RL_STATE_CALLBACK
))
233 _rl_arg_dispatch (_rl_argcxt
, key
);
234 rl_message ("(arg: %d) ", rl_arg_sign
* rl_numeric_arg
);
239 rl_execute_next (key
);
240 return (rl_digit_loop ());
244 /* C-u, universal argument. Multiply the current argument by 4.
245 Read a key. If the key has nothing to do with arguments, then
246 dispatch on it. If the key is the abort character then abort. */
248 rl_universal_argument (int count
, int key
)
253 return (RL_ISSTATE (RL_STATE_CALLBACK
) ? 0 : rl_digit_loop ());
257 _rl_arg_callback (_rl_arg_cxt cxt
)
261 c
= _rl_arg_getchar ();
263 return (1); /* EOF */
265 if (_rl_argcxt
& NUM_READONE
)
267 _rl_argcxt
&= ~NUM_READONE
;
268 rl_restore_prompt ();
270 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
275 r
= _rl_arg_dispatch (cxt
, c
);
277 rl_message ("(arg: %d) ", rl_arg_sign
* rl_numeric_arg
);
281 /* What to do when you abort reading an argument. */
283 rl_discard_argument (void)
287 _rl_reset_argument ();
292 /* **************************************************************** */
294 /* History Utilities */
296 /* **************************************************************** */
298 /* We already have a history library, and that is what we use to control
299 the history features of readline. This is our local interface to
300 the history mechanism. */
302 /* While we are editing the history, this is the saved
303 version of the original line. */
304 HIST_ENTRY
*_rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
306 /* Set the history pointer back to the last entry in the history. */
308 _rl_start_using_history (void)
311 if (_rl_saved_line_for_history
)
312 _rl_free_history_entry (_rl_saved_line_for_history
);
314 _rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
317 /* Free the contents (and containing structure) of a HIST_ENTRY. */
319 _rl_free_history_entry (HIST_ENTRY
*entry
)
325 FREE (entry
->timestamp
);
330 /* Perhaps put back the current line if it has changed. */
332 rl_maybe_replace_line (void)
336 temp
= current_history ();
337 /* If the current line has changed, save the changes. */
338 if (temp
&& ((UNDO_LIST
*)(temp
->data
) != rl_undo_list
))
340 temp
= replace_history_entry (where_history (), rl_line_buffer
, (histdata_t
)rl_undo_list
);
342 FREE (temp
->timestamp
);
348 /* Restore the _rl_saved_line_for_history if there is one. */
350 rl_maybe_unsave_line (void)
352 if (_rl_saved_line_for_history
)
354 /* Can't call with `1' because rl_undo_list might point to an undo
355 list from a history entry, as in rl_replace_from_history() below. */
356 rl_replace_line (_rl_saved_line_for_history
->line
, 0);
357 rl_undo_list
= (UNDO_LIST
*)_rl_saved_line_for_history
->data
;
358 _rl_free_history_entry (_rl_saved_line_for_history
);
359 _rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
360 rl_point
= rl_end
; /* rl_replace_line sets rl_end */
367 /* Save the current line in _rl_saved_line_for_history. */
369 rl_maybe_save_line (void)
371 if (_rl_saved_line_for_history
== 0)
373 _rl_saved_line_for_history
= (HIST_ENTRY
*)xmalloc (sizeof (HIST_ENTRY
));
374 _rl_saved_line_for_history
->line
= savestring (rl_line_buffer
);
375 _rl_saved_line_for_history
->timestamp
= (char *)NULL
;
376 _rl_saved_line_for_history
->data
= (char *)rl_undo_list
;
383 _rl_free_saved_history_line (void)
385 if (_rl_saved_line_for_history
)
387 _rl_free_history_entry (_rl_saved_line_for_history
);
388 _rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
394 _rl_history_set_point (void)
396 rl_point
= (_rl_history_preserve_point
&& _rl_history_saved_point
!= -1)
397 ? _rl_history_saved_point
399 if (rl_point
> rl_end
)
402 #if defined (VI_MODE)
403 if (rl_editing_mode
== vi_mode
&& _rl_keymap
!= vi_insertion_keymap
)
407 if (rl_editing_mode
== emacs_mode
)
408 rl_mark
= (rl_point
== rl_end
? 0 : rl_end
);
412 rl_replace_from_history (HIST_ENTRY
*entry
, int flags
)
414 /* Can't call with `1' because rl_undo_list might point to an undo list
415 from a history entry, just like we're setting up here. */
416 rl_replace_line (entry
->line
, 0);
417 rl_undo_list
= (UNDO_LIST
*)entry
->data
;
421 #if defined (VI_MODE)
422 if (rl_editing_mode
== vi_mode
)
430 /* Process and free undo lists attached to each history entry prior to the
431 current entry, inclusive, reverting each line to its saved state. This
432 is destructive, and state about the current line is lost. This is not
433 intended to be called while actively editing, and the current line is
434 not assumed to have been added to the history list. */
436 _rl_revert_previous_lines (void)
440 UNDO_LIST
*ul
, *saved_undo_list
;
443 lbuf
= savestring (rl_line_buffer
);
444 saved_undo_list
= rl_undo_list
;
445 hpos
= where_history ();
447 entry
= (hpos
== history_length
) ? previous_history () : current_history ();
450 if (ul
= (UNDO_LIST
*)entry
->data
)
452 if (ul
== saved_undo_list
)
454 /* Set up rl_line_buffer and other variables from history entry */
455 rl_replace_from_history (entry
, 0); /* entry->line is now current */
456 entry
->data
= 0; /* entry->data is now current undo list */
457 /* Undo all changes to this history entry */
460 /* And copy the reverted line back to the history entry, preserving
463 entry
->line
= savestring (rl_line_buffer
);
465 entry
= previous_history ();
468 /* Restore history state */
469 rl_undo_list
= saved_undo_list
; /* may have been set to null */
470 history_set_pos (hpos
);
472 /* reset the line buffer */
473 rl_replace_line (lbuf
, 0);
480 /* Revert all lines in the history by making sure we are at the end of the
481 history before calling _rl_revert_previous_lines() */
483 _rl_revert_all_lines (void)
487 pos
= where_history ();
489 _rl_revert_previous_lines ();
490 history_set_pos (pos
);
493 /* Free the history list, including private readline data and take care
494 of pointer aliases to history data. Resets rl_undo_list if it points
495 to an UNDO_LIST * saved as some history entry's data member. This
496 should not be called while editing is active. */
498 rl_clear_history (void)
500 HIST_ENTRY
**hlist
, *hent
;
502 UNDO_LIST
*ul
, *saved_undo_list
;
504 saved_undo_list
= rl_undo_list
;
505 hlist
= history_list (); /* direct pointer, not copy */
507 for (i
= 0; i
< history_length
; i
++)
510 if (ul
= (UNDO_LIST
*)hent
->data
)
512 if (ul
== saved_undo_list
)
514 _rl_free_undo_list (ul
);
517 _rl_free_history_entry (hent
);
520 history_offset
= history_length
= 0;
521 rl_undo_list
= saved_undo_list
; /* should be NULL */
524 /* **************************************************************** */
526 /* History Commands */
528 /* **************************************************************** */
530 /* Meta-< goes to the start of the history. */
532 rl_beginning_of_history (int count
, int key
)
534 return (rl_get_previous_history (1 + where_history (), key
));
537 /* Meta-> goes to the end of the history. (The current line). */
539 rl_end_of_history (int count
, int key
)
541 rl_maybe_replace_line ();
543 rl_maybe_unsave_line ();
547 /* Move down to the next history line. */
549 rl_get_next_history (int count
, int key
)
554 return (rl_get_previous_history (-count
, key
));
559 rl_maybe_replace_line ();
561 /* either not saved by rl_newline or at end of line, so set appropriately. */
562 if (_rl_history_saved_point
== -1 && (rl_point
|| rl_end
))
563 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
565 temp
= (HIST_ENTRY
*)NULL
;
568 temp
= next_history ();
575 rl_maybe_unsave_line ();
578 rl_replace_from_history (temp
, 0);
579 _rl_history_set_point ();
584 /* Get the previous item out of our interactive history, making it the current
585 line. If there is no previous history, just ding. */
587 rl_get_previous_history (int count
, int key
)
589 HIST_ENTRY
*old_temp
, *temp
;
593 return (rl_get_next_history (-count
, key
));
595 if (count
== 0 || history_list () == 0)
598 /* either not saved by rl_newline or at end of line, so set appropriately. */
599 if (_rl_history_saved_point
== -1 && (rl_point
|| rl_end
))
600 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
602 /* If we don't have a line saved, then save this one. */
603 had_saved_line
= _rl_saved_line_for_history
!= 0;
604 rl_maybe_save_line ();
606 /* If the current line has changed, save the changes. */
607 rl_maybe_replace_line ();
609 temp
= old_temp
= (HIST_ENTRY
*)NULL
;
612 temp
= previous_history ();
620 /* If there was a large argument, and we moved back to the start of the
621 history, that is not an error. So use the last value found. */
622 if (!temp
&& old_temp
)
627 if (had_saved_line
== 0)
628 _rl_free_saved_history_line ();
633 rl_replace_from_history (temp
, 0);
634 _rl_history_set_point ();
640 /* The equivalent of the Korn shell C-o operate-and-get-next-history-line
643 /* This could stand to be global to the readline library */
644 static rl_hook_func_t
*_rl_saved_internal_startup_hook
= 0;
645 static int saved_history_logical_offset
= -1;
647 #define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
652 int absolute_offset
, count
;
654 if (saved_history_logical_offset
>= 0)
656 absolute_offset
= saved_history_logical_offset
- history_base
;
657 count
= where_history () - absolute_offset
;
658 rl_get_previous_history (count
, 0);
660 saved_history_logical_offset
= -1;
661 _rl_internal_startup_hook
= _rl_saved_internal_startup_hook
;
667 rl_operate_and_get_next (count
, c
)
670 /* Accept the current line. */
673 saved_history_logical_offset
= rl_explicit_arg
? count
: where_history () + history_base
+ 1;
676 _rl_saved_internal_startup_hook
= _rl_internal_startup_hook
;
677 _rl_internal_startup_hook
= set_saved_history
;
682 /* **************************************************************** */
686 /* **************************************************************** */
687 /* How to toggle back and forth between editing modes. */
689 rl_vi_editing_mode (int count
, int key
)
691 #if defined (VI_MODE)
692 _rl_set_insert_mode (RL_IM_INSERT
, 1); /* vi mode ignores insert mode */
693 rl_editing_mode
= vi_mode
;
694 rl_vi_insert_mode (1, key
);
701 rl_emacs_editing_mode (int count
, int key
)
703 rl_editing_mode
= emacs_mode
;
704 _rl_set_insert_mode (RL_IM_INSERT
, 1); /* emacs mode default is insert mode */
705 _rl_keymap
= emacs_standard_keymap
;
707 if (_rl_show_mode_in_prompt
)
713 /* Function for the rest of the library to use to set insert/overwrite mode. */
715 _rl_set_insert_mode (int im
, int force
)
718 _rl_set_cursor (im
, force
);
724 /* Toggle overwrite mode. A positive explicit argument selects overwrite
725 mode. A negative or zero explicit argument selects insert mode. */
727 rl_overwrite_mode (int count
, int key
)
729 if (rl_explicit_arg
== 0)
730 _rl_set_insert_mode (rl_insert_mode
^ 1, 0);
732 _rl_set_insert_mode (RL_IM_OVERWRITE
, 0);
734 _rl_set_insert_mode (RL_IM_INSERT
, 0);