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))
217 /* Create a default argument. */
219 _rl_reset_argument ()
221 rl_numeric_arg
= rl_arg_sign
= 1;
226 /* Start a numeric argument with initial value KEY */
228 rl_digit_argument (ignore
, key
)
232 if (RL_ISSTATE (RL_STATE_CALLBACK
))
234 _rl_arg_dispatch (_rl_argcxt
, key
);
235 rl_message ("(arg: %d) ", rl_arg_sign
* rl_numeric_arg
);
240 rl_execute_next (key
);
241 return (rl_digit_loop ());
245 /* C-u, universal argument. Multiply the current argument by 4.
246 Read a key. If the key has nothing to do with arguments, then
247 dispatch on it. If the key is the abort character then abort. */
249 rl_universal_argument (count
, key
)
255 return (RL_ISSTATE (RL_STATE_CALLBACK
) ? 0 : rl_digit_loop ());
259 _rl_arg_callback (cxt
)
264 c
= _rl_arg_getchar ();
266 if (_rl_argcxt
& NUM_READONE
)
268 _rl_argcxt
&= ~NUM_READONE
;
269 rl_restore_prompt ();
271 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
276 r
= _rl_arg_dispatch (cxt
, c
);
280 /* What to do when you abort reading an argument. */
282 rl_discard_argument ()
286 _rl_reset_argument ();
291 /* **************************************************************** */
293 /* History Utilities */
295 /* **************************************************************** */
297 /* We already have a history library, and that is what we use to control
298 the history features of readline. This is our local interface to
299 the history mechanism. */
301 /* While we are editing the history, this is the saved
302 version of the original line. */
303 HIST_ENTRY
*_rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
305 /* Set the history pointer back to the last entry in the history. */
307 _rl_start_using_history ()
310 if (_rl_saved_line_for_history
)
311 _rl_free_history_entry (_rl_saved_line_for_history
);
313 _rl_saved_line_for_history
= (HIST_ENTRY
*)NULL
;
316 /* Free the contents (and containing structure) of a HIST_ENTRY. */
318 _rl_free_history_entry (entry
)
325 FREE (entry
->timestamp
);
330 /* Perhaps put back the current line if it has changed. */
332 rl_maybe_replace_line ()
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 ()
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 ()
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 ()
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 ()
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 (entry
, flags
)
414 int flags
; /* currently unused */
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 /* **************************************************************** */
434 /* History Commands */
436 /* **************************************************************** */
438 /* Meta-< goes to the start of the history. */
440 rl_beginning_of_history (count
, key
)
443 return (rl_get_previous_history (1 + where_history (), key
));
446 /* Meta-> goes to the end of the history. (The current line). */
448 rl_end_of_history (count
, key
)
451 rl_maybe_replace_line ();
453 rl_maybe_unsave_line ();
457 /* Move down to the next history line. */
459 rl_get_next_history (count
, key
)
465 return (rl_get_previous_history (-count
, key
));
470 rl_maybe_replace_line ();
472 /* either not saved by rl_newline or at end of line, so set appropriately. */
473 if (_rl_history_saved_point
== -1 && (rl_point
|| rl_end
))
474 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
476 temp
= (HIST_ENTRY
*)NULL
;
479 temp
= next_history ();
486 rl_maybe_unsave_line ();
489 rl_replace_from_history (temp
, 0);
490 _rl_history_set_point ();
495 /* Get the previous item out of our interactive history, making it the current
496 line. If there is no previous history, just ding. */
498 rl_get_previous_history (count
, key
)
501 HIST_ENTRY
*old_temp
, *temp
;
504 return (rl_get_next_history (-count
, key
));
509 /* either not saved by rl_newline or at end of line, so set appropriately. */
510 if (_rl_history_saved_point
== -1 && (rl_point
|| rl_end
))
511 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
513 /* If we don't have a line saved, then save this one. */
514 rl_maybe_save_line ();
516 /* If the current line has changed, save the changes. */
517 rl_maybe_replace_line ();
519 temp
= old_temp
= (HIST_ENTRY
*)NULL
;
522 temp
= previous_history ();
530 /* If there was a large argument, and we moved back to the start of the
531 history, that is not an error. So use the last value found. */
532 if (!temp
&& old_temp
)
539 rl_replace_from_history (temp
, 0);
540 _rl_history_set_point ();
546 /* **************************************************************** */
550 /* **************************************************************** */
551 /* How to toggle back and forth between editing modes. */
553 rl_vi_editing_mode (count
, key
)
556 #if defined (VI_MODE)
557 _rl_set_insert_mode (RL_IM_INSERT
, 1); /* vi mode ignores insert mode */
558 rl_editing_mode
= vi_mode
;
559 rl_vi_insertion_mode (1, key
);
566 rl_emacs_editing_mode (count
, key
)
569 rl_editing_mode
= emacs_mode
;
570 _rl_set_insert_mode (RL_IM_INSERT
, 1); /* emacs mode default is insert mode */
571 _rl_keymap
= emacs_standard_keymap
;
575 /* Function for the rest of the library to use to set insert/overwrite mode. */
577 _rl_set_insert_mode (im
, force
)
581 _rl_set_cursor (im
, force
);
587 /* Toggle overwrite mode. A positive explicit argument selects overwrite
588 mode. A negative or zero explicit argument selects insert mode. */
590 rl_overwrite_mode (count
, key
)
593 if (rl_explicit_arg
== 0)
594 _rl_set_insert_mode (rl_insert_mode
^ 1, 0);
596 _rl_set_insert_mode (RL_IM_OVERWRITE
, 0);
598 _rl_set_insert_mode (RL_IM_INSERT
, 0);