1 /* misc.c -- miscellaneous bindable readline functions. */
3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
8 The GNU Readline Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2, or
11 (at your option) any later version.
13 The GNU Readline Library is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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);
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 ()
223 rl_numeric_arg = rl_arg_sign = 1;
228 /* Start a numeric argument with initial value KEY */
230 rl_digit_argument (ignore, key)
234 if (RL_ISSTATE (RL_STATE_CALLBACK))
236 _rl_arg_dispatch (_rl_argcxt, key);
237 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
242 rl_execute_next (key);
243 return (rl_digit_loop ());
247 /* C-u, universal argument. Multiply the current argument by 4.
248 Read a key. If the key has nothing to do with arguments, then
249 dispatch on it. If the key is the abort character then abort. */
251 rl_universal_argument (count, key)
257 return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
261 _rl_arg_callback (cxt)
266 c = _rl_arg_getchar ();
268 if (_rl_argcxt & NUM_READONE)
270 _rl_argcxt &= ~NUM_READONE;
271 rl_restore_prompt ();
273 RL_UNSETSTATE(RL_STATE_NUMERICARG);
278 r = _rl_arg_dispatch (cxt, c);
282 /* What to do when you abort reading an argument. */
284 rl_discard_argument ()
288 _rl_reset_argument ();
293 /* **************************************************************** */
295 /* History Utilities */
297 /* **************************************************************** */
299 /* We already have a history library, and that is what we use to control
300 the history features of readline. This is our local interface to
301 the history mechanism. */
303 /* While we are editing the history, this is the saved
304 version of the original line. */
305 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
307 /* Set the history pointer back to the last entry in the history. */
309 _rl_start_using_history ()
312 if (_rl_saved_line_for_history)
313 _rl_free_history_entry (_rl_saved_line_for_history);
315 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
318 /* Free the contents (and containing structure) of a HIST_ENTRY. */
320 _rl_free_history_entry (entry)
327 FREE (entry->timestamp);
332 /* Perhaps put back the current line if it has changed. */
334 rl_maybe_replace_line ()
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 ()
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 ()
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 ()
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 ()
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 (entry, flags)
416 int flags; /* currently unused */
418 /* Can't call with `1' because rl_undo_list might point to an undo list
419 from a history entry, just like we're setting up here. */
420 rl_replace_line (entry->line, 0);
421 rl_undo_list = (UNDO_LIST *)entry->data;
425 #if defined (VI_MODE)
426 if (rl_editing_mode == vi_mode)
434 /* **************************************************************** */
436 /* History Commands */
438 /* **************************************************************** */
440 /* Meta-< goes to the start of the history. */
442 rl_beginning_of_history (count, key)
445 return (rl_get_previous_history (1 + where_history (), key));
448 /* Meta-> goes to the end of the history. (The current line). */
450 rl_end_of_history (count, key)
453 rl_maybe_replace_line ();
455 rl_maybe_unsave_line ();
459 /* Move down to the next history line. */
461 rl_get_next_history (count, key)
467 return (rl_get_previous_history (-count, key));
472 rl_maybe_replace_line ();
474 /* either not saved by rl_newline or at end of line, so set appropriately. */
475 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
476 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
478 temp = (HIST_ENTRY *)NULL;
481 temp = next_history ();
488 rl_maybe_unsave_line ();
491 rl_replace_from_history (temp, 0);
492 _rl_history_set_point ();
497 /* Get the previous item out of our interactive history, making it the current
498 line. If there is no previous history, just ding. */
500 rl_get_previous_history (count, key)
503 HIST_ENTRY *old_temp, *temp;
506 return (rl_get_next_history (-count, key));
511 /* either not saved by rl_newline or at end of line, so set appropriately. */
512 if (_rl_history_saved_point == -1 && (rl_point || rl_end))
513 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
515 /* If we don't have a line saved, then save this one. */
516 rl_maybe_save_line ();
518 /* If the current line has changed, save the changes. */
519 rl_maybe_replace_line ();
521 temp = old_temp = (HIST_ENTRY *)NULL;
524 temp = previous_history ();
532 /* If there was a large argument, and we moved back to the start of the
533 history, that is not an error. So use the last value found. */
534 if (!temp && old_temp)
541 rl_replace_from_history (temp, 0);
542 _rl_history_set_point ();
548 /* **************************************************************** */
552 /* **************************************************************** */
553 /* How to toggle back and forth between editing modes. */
555 rl_vi_editing_mode (count, key)
558 #if defined (VI_MODE)
559 _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
560 rl_editing_mode = vi_mode;
561 rl_vi_insertion_mode (1, key);
568 rl_emacs_editing_mode (count, key)
571 rl_editing_mode = emacs_mode;
572 _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
573 _rl_keymap = emacs_standard_keymap;
577 /* Function for the rest of the library to use to set insert/overwrite mode. */
579 _rl_set_insert_mode (im, force)
583 _rl_set_cursor (im, force);
589 /* Toggle overwrite mode. A positive explicit argument selects overwrite
590 mode. A negative or zero explicit argument selects insert mode. */
592 rl_overwrite_mode (count, key)
595 if (rl_explicit_arg == 0)
596 _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
598 _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
600 _rl_set_insert_mode (RL_IM_INSERT, 0);