import of readlilne 5.1
[deliverable/binutils-gdb.git] / readline / misc.c
CommitLineData
84041b4c
EZ
1/* misc.c -- miscellaneous bindable readline functions. */
2
b585a9fa 3/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
84041b4c
EZ
4
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
7
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.
12
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.
17
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
23
24#if defined (HAVE_CONFIG_H)
25# include <config.h>
26#endif
27
28#if defined (HAVE_UNISTD_H)
29# include <unistd.h>
30#endif /* HAVE_UNISTD_H */
31
32#if defined (HAVE_STDLIB_H)
33# include <stdlib.h>
34#else
35# include "ansi_stdlib.h"
36#endif /* HAVE_STDLIB_H */
37
38#if defined (HAVE_LOCALE_H)
39# include <locale.h>
40#endif
41
42#include <stdio.h>
43
44/* System-specific feature definitions and include files. */
45#include "rldefs.h"
46#include "rlmbutil.h"
47
48/* Some standard library routines. */
49#include "readline.h"
50#include "history.h"
51
52#include "rlprivate.h"
53#include "rlshell.h"
54#include "xmalloc.h"
55
56static int rl_digit_loop PARAMS((void));
57static void _rl_history_set_point PARAMS((void));
58
59/* Forward declarations used in this file */
60void _rl_free_history_entry PARAMS((HIST_ENTRY *));
61
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. */
64int _rl_history_preserve_point = 0;
65
b585a9fa
EZ
66_rl_arg_cxt _rl_argcxt;
67
84041b4c
EZ
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. */
70int _rl_history_saved_point = -1;
71
72/* **************************************************************** */
73/* */
74/* Numeric Arguments */
75/* */
76/* **************************************************************** */
77
b585a9fa
EZ
78int
79_rl_arg_overflow ()
84041b4c 80{
b585a9fa
EZ
81 if (rl_numeric_arg > 1000000)
82 {
83 _rl_argcxt = 0;
84 rl_explicit_arg = rl_numeric_arg = 0;
85 rl_ding ();
86 rl_restore_prompt ();
87 rl_clear_message ();
88 RL_UNSETSTATE(RL_STATE_NUMERICARG);
89 return 1;
90 }
91 return 0;
92}
84041b4c 93
b585a9fa
EZ
94void
95_rl_arg_init ()
96{
84041b4c 97 rl_save_prompt ();
b585a9fa 98 _rl_argcxt = 0;
84041b4c 99 RL_SETSTATE(RL_STATE_NUMERICARG);
b585a9fa 100}
84041b4c 101
b585a9fa
EZ
102int
103_rl_arg_getchar ()
104{
105 int c;
84041b4c 106
b585a9fa
EZ
107 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
108 RL_SETSTATE(RL_STATE_MOREINPUT);
109 c = rl_read_key ();
110 RL_UNSETSTATE(RL_STATE_MOREINPUT);
84041b4c 111
b585a9fa
EZ
112 return c;
113}
84041b4c 114
b585a9fa
EZ
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. */
118int
119_rl_arg_dispatch (cxt, c)
120 _rl_arg_cxt cxt;
121 int c;
122{
123 int key, r;
124
125 key = c;
126
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)
130 {
131 if ((cxt & NUM_SAWDIGITS) == 0)
84041b4c 132 {
b585a9fa
EZ
133 rl_numeric_arg *= 4;
134 return 1;
84041b4c 135 }
b585a9fa
EZ
136 else if (RL_ISSTATE (RL_STATE_CALLBACK))
137 {
138 _rl_argcxt |= NUM_READONE;
139 return 0; /* XXX */
140 }
84041b4c
EZ
141 else
142 {
b585a9fa
EZ
143 RL_SETSTATE(RL_STATE_MOREINPUT);
144 key = rl_read_key ();
145 RL_UNSETSTATE(RL_STATE_MOREINPUT);
84041b4c
EZ
146 rl_restore_prompt ();
147 rl_clear_message ();
148 RL_UNSETSTATE(RL_STATE_NUMERICARG);
149 return (_rl_dispatch (key, _rl_keymap));
150 }
151 }
152
b585a9fa 153 c = UNMETA (c);
84041b4c 154
b585a9fa
EZ
155 if (_rl_digit_p (c))
156 {
157 r = _rl_digit_value (c);
158 rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
159 rl_explicit_arg = 1;
160 _rl_argcxt |= NUM_SAWDIGITS;
161 }
162 else if (c == '-' && rl_explicit_arg == 0)
163 {
164 rl_numeric_arg = 1;
165 _rl_argcxt |= NUM_SAWMINUS;
166 rl_arg_sign = -1;
167 }
168 else
169 {
170 /* Make M-- command equivalent to M--1 command. */
171 if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
172 rl_explicit_arg = 1;
173 rl_restore_prompt ();
174 rl_clear_message ();
175 RL_UNSETSTATE(RL_STATE_NUMERICARG);
176
177 r = _rl_dispatch (key, _rl_keymap);
178 if (RL_ISSTATE (RL_STATE_CALLBACK))
179 {
180 /* At worst, this will cause an extra redisplay. Otherwise,
181 we have to wait until the next character comes in. */
182 if (rl_done == 0)
183 (*rl_redisplay_function) ();
184 r = 0;
185 }
186 return r;
187 }
188
189 return 1;
84041b4c
EZ
190}
191
b585a9fa
EZ
192/* Handle C-u style numeric args, as well as M--, and M-digits. */
193static int
194rl_digit_loop ()
84041b4c 195{
b585a9fa
EZ
196 int c, r;
197
198 while (1)
199 {
200 if (_rl_arg_overflow ())
201 return 1;
202
203 c = _rl_arg_getchar ();
204
205 if (c < 0)
206 {
207 _rl_abort_internal ();
208 return -1;
209 }
210
211 r = _rl_arg_dispatch (_rl_argcxt, c);
212 if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
213 break;
214 }
84041b4c
EZ
215}
216
217/* Create a default argument. */
b585a9fa
EZ
218void
219_rl_reset_argument ()
84041b4c
EZ
220{
221 rl_numeric_arg = rl_arg_sign = 1;
222 rl_explicit_arg = 0;
b585a9fa
EZ
223 _rl_argcxt = 0;
224}
225
226/* Start a numeric argument with initial value KEY */
227int
228rl_digit_argument (ignore, key)
229 int ignore, key;
230{
231 _rl_arg_init ();
232 if (RL_ISSTATE (RL_STATE_CALLBACK))
233 {
234 _rl_arg_dispatch (_rl_argcxt, key);
235 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
236 return 0;
237 }
238 else
239 {
240 rl_execute_next (key);
241 return (rl_digit_loop ());
242 }
84041b4c
EZ
243}
244
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. */
248int
249rl_universal_argument (count, key)
250 int count, key;
251{
b585a9fa 252 _rl_arg_init ();
84041b4c 253 rl_numeric_arg *= 4;
b585a9fa
EZ
254
255 return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
256}
257
258int
259_rl_arg_callback (cxt)
260 _rl_arg_cxt cxt;
261{
262 int c, r;
263
264 c = _rl_arg_getchar ();
265
266 if (_rl_argcxt & NUM_READONE)
267 {
268 _rl_argcxt &= ~NUM_READONE;
269 rl_restore_prompt ();
270 rl_clear_message ();
271 RL_UNSETSTATE(RL_STATE_NUMERICARG);
272 rl_execute_next (c);
273 return 0;
274 }
275
276 r = _rl_arg_dispatch (cxt, c);
277 return (r != 1);
278}
279
280/* What to do when you abort reading an argument. */
281int
282rl_discard_argument ()
283{
284 rl_ding ();
285 rl_clear_message ();
286 _rl_reset_argument ();
287
288 return 0;
84041b4c
EZ
289}
290
291/* **************************************************************** */
292/* */
293/* History Utilities */
294/* */
295/* **************************************************************** */
296
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. */
300
301/* While we are editing the history, this is the saved
302 version of the original line. */
303HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
304
305/* Set the history pointer back to the last entry in the history. */
306void
307_rl_start_using_history ()
308{
309 using_history ();
310 if (_rl_saved_line_for_history)
311 _rl_free_history_entry (_rl_saved_line_for_history);
312
313 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
314}
315
316/* Free the contents (and containing structure) of a HIST_ENTRY. */
317void
318_rl_free_history_entry (entry)
319 HIST_ENTRY *entry;
320{
321 if (entry == 0)
322 return;
b585a9fa
EZ
323
324 FREE (entry->line);
325 FREE (entry->timestamp);
326
84041b4c
EZ
327 free (entry);
328}
329
330/* Perhaps put back the current line if it has changed. */
331int
332rl_maybe_replace_line ()
333{
334 HIST_ENTRY *temp;
335
336 temp = current_history ();
337 /* If the current line has changed, save the changes. */
338 if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
339 {
340 temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
341 free (temp->line);
b585a9fa 342 FREE (temp->timestamp);
84041b4c
EZ
343 free (temp);
344 }
345 return 0;
346}
347
348/* Restore the _rl_saved_line_for_history if there is one. */
349int
350rl_maybe_unsave_line ()
351{
352 if (_rl_saved_line_for_history)
353 {
b585a9fa
EZ
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. */
84041b4c
EZ
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 */
361 }
362 else
363 rl_ding ();
364 return 0;
365}
366
367/* Save the current line in _rl_saved_line_for_history. */
368int
369rl_maybe_save_line ()
370{
371 if (_rl_saved_line_for_history == 0)
372 {
373 _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
374 _rl_saved_line_for_history->line = savestring (rl_line_buffer);
b585a9fa 375 _rl_saved_line_for_history->timestamp = (char *)NULL;
84041b4c
EZ
376 _rl_saved_line_for_history->data = (char *)rl_undo_list;
377 }
b585a9fa 378
84041b4c
EZ
379 return 0;
380}
381
382int
383_rl_free_saved_history_line ()
384{
385 if (_rl_saved_line_for_history)
386 {
387 _rl_free_history_entry (_rl_saved_line_for_history);
388 _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
389 }
390 return 0;
391}
392
393static void
394_rl_history_set_point ()
395{
396 rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
397 ? _rl_history_saved_point
398 : rl_end;
399 if (rl_point > rl_end)
400 rl_point = rl_end;
401
402#if defined (VI_MODE)
b585a9fa 403 if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
84041b4c
EZ
404 rl_point = 0;
405#endif /* VI_MODE */
406
407 if (rl_editing_mode == emacs_mode)
408 rl_mark = (rl_point == rl_end ? 0 : rl_end);
409}
410
411void
412rl_replace_from_history (entry, flags)
413 HIST_ENTRY *entry;
414 int flags; /* currently unused */
415{
b585a9fa
EZ
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. */
84041b4c
EZ
418 rl_replace_line (entry->line, 0);
419 rl_undo_list = (UNDO_LIST *)entry->data;
420 rl_point = rl_end;
421 rl_mark = 0;
422
423#if defined (VI_MODE)
424 if (rl_editing_mode == vi_mode)
425 {
426 rl_point = 0;
427 rl_mark = rl_end;
428 }
429#endif
430}
431
432/* **************************************************************** */
433/* */
434/* History Commands */
435/* */
436/* **************************************************************** */
437
438/* Meta-< goes to the start of the history. */
439int
440rl_beginning_of_history (count, key)
441 int count, key;
442{
443 return (rl_get_previous_history (1 + where_history (), key));
444}
445
446/* Meta-> goes to the end of the history. (The current line). */
447int
448rl_end_of_history (count, key)
449 int count, key;
450{
451 rl_maybe_replace_line ();
452 using_history ();
453 rl_maybe_unsave_line ();
454 return 0;
455}
456
457/* Move down to the next history line. */
458int
459rl_get_next_history (count, key)
460 int count, key;
461{
462 HIST_ENTRY *temp;
463
464 if (count < 0)
465 return (rl_get_previous_history (-count, key));
466
467 if (count == 0)
468 return 0;
469
470 rl_maybe_replace_line ();
471
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;
475
476 temp = (HIST_ENTRY *)NULL;
477 while (count)
478 {
479 temp = next_history ();
480 if (!temp)
481 break;
482 --count;
483 }
484
485 if (temp == 0)
486 rl_maybe_unsave_line ();
487 else
488 {
489 rl_replace_from_history (temp, 0);
490 _rl_history_set_point ();
491 }
492 return 0;
493}
494
495/* Get the previous item out of our interactive history, making it the current
496 line. If there is no previous history, just ding. */
497int
498rl_get_previous_history (count, key)
499 int count, key;
500{
501 HIST_ENTRY *old_temp, *temp;
502
503 if (count < 0)
504 return (rl_get_next_history (-count, key));
505
506 if (count == 0)
507 return 0;
508
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;
512
513 /* If we don't have a line saved, then save this one. */
514 rl_maybe_save_line ();
515
516 /* If the current line has changed, save the changes. */
517 rl_maybe_replace_line ();
518
519 temp = old_temp = (HIST_ENTRY *)NULL;
520 while (count)
521 {
522 temp = previous_history ();
523 if (temp == 0)
524 break;
525
526 old_temp = temp;
527 --count;
528 }
529
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)
533 temp = old_temp;
534
535 if (temp == 0)
536 rl_ding ();
537 else
538 {
539 rl_replace_from_history (temp, 0);
540 _rl_history_set_point ();
541 }
b585a9fa 542
84041b4c
EZ
543 return 0;
544}
545
546/* **************************************************************** */
547/* */
548/* Editing Modes */
549/* */
550/* **************************************************************** */
551/* How to toggle back and forth between editing modes. */
552int
553rl_vi_editing_mode (count, key)
554 int count, key;
555{
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);
560#endif /* VI_MODE */
561
562 return 0;
563}
564
565int
566rl_emacs_editing_mode (count, key)
567 int count, key;
568{
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;
572 return 0;
573}
574
575/* Function for the rest of the library to use to set insert/overwrite mode. */
576void
577_rl_set_insert_mode (im, force)
578 int im, force;
579{
580#ifdef CURSOR_MODE
581 _rl_set_cursor (im, force);
582#endif
583
584 rl_insert_mode = im;
585}
586
587/* Toggle overwrite mode. A positive explicit argument selects overwrite
588 mode. A negative or zero explicit argument selects insert mode. */
589int
590rl_overwrite_mode (count, key)
591 int count, key;
592{
593 if (rl_explicit_arg == 0)
594 _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
595 else if (count > 0)
596 _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
597 else
598 _rl_set_insert_mode (RL_IM_INSERT, 0);
599
600 return 0;
601}
This page took 0.04514 seconds and 4 git commands to generate.