1 /* misc.c -- miscellaneous bindable readline functions. */
3 /* Copyright (C) 1987-2009 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 (_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 if (_rl_argcxt & NUM_READONE)
272 _rl_argcxt &= ~NUM_READONE;
273 rl_restore_prompt ();
275 RL_UNSETSTATE(RL_STATE_NUMERICARG);
280 r = _rl_arg_dispatch (cxt, c);
284 /* What to do when you abort reading an argument. */
286 rl_discard_argument ()
290 _rl_reset_argument ();
295 /* **************************************************************** */
297 /* History Utilities */
299 /* **************************************************************** */
301 /* We already have a history library, and that is what we use to control
302 the history features of readline. This is our local interface to
303 the history mechanism. */
305 /* While we are editing the history, this is the saved
306 version of the original line. */
307 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
309 /* Set the history pointer back to the last entry in the history. */
311 _rl_start_using_history ()
314 if (_rl_saved_line_for_history)
315 _rl_free_history_entry (_rl_saved_line_for_history);
317 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
320 /* Free the contents (and containing structure) of a HIST_ENTRY. */
322 _rl_free_history_entry (entry)
329 FREE (entry->timestamp);
334 /* Perhaps put back the current line if it has changed. */
336 rl_maybe_replace_line ()
340 temp = current_history ();
341 /* If the current line has changed, save the changes. */
342 if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
344 temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
346 FREE (temp->timestamp);
352 /* Restore the _rl_saved_line_for_history if there is one. */
354 rl_maybe_unsave_line ()
356 if (_rl_saved_line_for_history)
358 /* Can't call with `1' because rl_undo_list might point to an undo
359 list from a history entry, as in rl_replace_from_history() below. */
360 rl_replace_line (_rl_saved_line_for_history->line, 0);
361 rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
362 _rl_free_history_entry (_rl_saved_line_for_history);
363 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
364 rl_point = rl_end; /* rl_replace_line sets rl_end */
371 /* Save the current line in _rl_saved_line_for_history. */
373 rl_maybe_save_line ()
375 if (_rl_saved_line_for_history == 0)
377 _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
378 _rl_saved_line_for_history->line = savestring (rl_line_buffer);
379 _rl_saved_line_for_history->timestamp = (char *)NULL;
380 _rl_saved_line_for_history->data = (char *)rl_undo_list;
387 _rl_free_saved_history_line ()
389 if (_rl_saved_line_for_history)
391 _rl_free_history_entry (_rl_saved_line_for_history);
392 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
398 _rl_history_set_point ()
400 rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
401 ? _rl_history_saved_point
403 if (rl_point > rl_end)
406 #if defined (VI_MODE)
407 if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
411 if (rl_editing_mode == emacs_mode)
412 rl_mark = (rl_point == rl_end ? 0 : rl_end);
416 rl_replace_from_history (entry, flags)
418 int flags; /* currently unused */
420 /* Can't call with `1' because rl_undo_list might point to an undo list
421 from a history entry, just like we're setting up here. */
422 rl_replace_line (entry->line, 0);
423 rl_undo_list = (UNDO_LIST *)entry->data;
427 #if defined (VI_MODE)
428 if (rl_editing_mode == vi_mode)
436 /* Process and free undo lists attached to each history entry prior to the
437 current entry, inclusive, reverting each line to its saved state. This
438 is destructive, and state about the current line is lost. This is not
439 intended to be called while actively editing, and the current line is
440 not assumed to have been added to the history list. */
442 _rl_revert_all_lines ()
446 UNDO_LIST *ul, *saved_undo_list;
449 lbuf = savestring (rl_line_buffer);
450 saved_undo_list = rl_undo_list;
451 hpos = where_history ();
453 entry = (hpos == history_length) ? previous_history () : current_history ();
456 if (ul = (UNDO_LIST *)entry->data)
458 if (ul == saved_undo_list)
460 /* Set up rl_line_buffer and other variables from history entry */
461 rl_replace_from_history (entry, 0); /* entry->line is now current */
462 /* Undo all changes to this history entry */
465 /* And copy the reverted line back to the history entry, preserving
468 entry->line = savestring (rl_line_buffer);
471 entry = previous_history ();
474 /* Restore history state */
475 rl_undo_list = saved_undo_list; /* may have been set to null */
476 history_set_pos (hpos);
478 /* reset the line buffer */
479 rl_replace_line (lbuf, 0);
486 /* **************************************************************** */
488 /* History Commands */
490 /* **************************************************************** */
492 /* Meta-< goes to the start of the history. */
494 rl_beginning_of_history (count, key)
497 return (rl_get_previous_history (1 + where_history (), key));
500 /* Meta-> goes to the end of the history. (The current line). */
502 rl_end_of_history (count, key)
505 rl_maybe_replace_line ();
507 rl_maybe_unsave_line ();
511 /* Move down to the next history line. */
513 rl_get_next_history (count, key)
519 return (rl_get_previous_history (-count, key));
524 rl_maybe_replace_line ();
526 /* either not saved by rl_newline or at end of line, so set appropriately. */
527 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
528 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
530 temp = (HIST_ENTRY *)NULL;
533 temp = next_history ();
540 rl_maybe_unsave_line ();
543 rl_replace_from_history (temp, 0);
544 _rl_history_set_point ();
549 /* Get the previous item out of our interactive history, making it the current
550 line. If there is no previous history, just ding. */
552 rl_get_previous_history (count, key)
555 HIST_ENTRY *old_temp, *temp;
558 return (rl_get_next_history (-count, key));
563 /* either not saved by rl_newline or at end of line, so set appropriately. */
564 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
565 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
567 /* If we don't have a line saved, then save this one. */
568 rl_maybe_save_line ();
570 /* If the current line has changed, save the changes. */
571 rl_maybe_replace_line ();
573 temp = old_temp = (HIST_ENTRY *)NULL;
576 temp = previous_history ();
584 /* If there was a large argument, and we moved back to the start of the
585 history, that is not an error. So use the last value found. */
586 if (!temp && old_temp)
593 rl_replace_from_history (temp, 0);
594 _rl_history_set_point ();
600 /* **************************************************************** */
604 /* **************************************************************** */
605 /* How to toggle back and forth between editing modes. */
607 rl_vi_editing_mode (count, key)
610 #if defined (VI_MODE)
611 _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
612 rl_editing_mode = vi_mode;
613 rl_vi_insert_mode (1, key);
620 rl_emacs_editing_mode (count, key)
623 rl_editing_mode = emacs_mode;
624 _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
625 _rl_keymap = emacs_standard_keymap;
629 /* Function for the rest of the library to use to set insert/overwrite mode. */
631 _rl_set_insert_mode (im, force)
635 _rl_set_cursor (im, force);
641 /* Toggle overwrite mode. A positive explicit argument selects overwrite
642 mode. A negative or zero explicit argument selects insert mode. */
644 rl_overwrite_mode (count, key)
647 if (rl_explicit_arg == 0)
648 _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
650 _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
652 _rl_set_insert_mode (RL_IM_INSERT, 0);