Imported from ../bash-3.0.16.tar.gz.
[platform/upstream/bash.git] / lib / readline / misc.c
1 /* misc.c -- miscellaneous bindable readline functions. */
2
3 /* Copyright (C) 1987-2004 Free Software Foundation, Inc.
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
56 static int rl_digit_loop PARAMS((void));
57 static void _rl_history_set_point PARAMS((void));
58
59 /* Forward declarations used in this file */
60 void _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. */
64 int _rl_history_preserve_point = 0;
65
66 /* Saved target point for when _rl_history_preserve_point is set.  Special
67    value of -1 means that point is at the end of the line. */
68 int _rl_history_saved_point = -1;
69
70 /* **************************************************************** */
71 /*                                                                  */
72 /*                      Numeric Arguments                           */
73 /*                                                                  */
74 /* **************************************************************** */
75
76 /* Handle C-u style numeric args, as well as M--, and M-digits. */
77 static int
78 rl_digit_loop ()
79 {
80   int key, c, sawminus, sawdigits;
81
82   rl_save_prompt ();
83
84   RL_SETSTATE(RL_STATE_NUMERICARG);
85   sawminus = sawdigits = 0;
86   while (1)
87     {
88       if (rl_numeric_arg > 1000000)
89         {
90           sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
91           rl_ding ();
92           rl_restore_prompt ();
93           rl_clear_message ();
94           RL_UNSETSTATE(RL_STATE_NUMERICARG);
95           return 1;
96         }
97       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
98       RL_SETSTATE(RL_STATE_MOREINPUT);
99       key = c = rl_read_key ();
100       RL_UNSETSTATE(RL_STATE_MOREINPUT);
101
102       if (c < 0)
103         {
104           _rl_abort_internal ();
105           return -1;
106         }
107
108       /* If we see a key bound to `universal-argument' after seeing digits,
109          it ends the argument but is otherwise ignored. */
110       if (_rl_keymap[c].type == ISFUNC &&
111           _rl_keymap[c].function == rl_universal_argument)
112         {
113           if (sawdigits == 0)
114             {
115               rl_numeric_arg *= 4;
116               continue;
117             }
118           else
119             {
120               RL_SETSTATE(RL_STATE_MOREINPUT);
121               key = rl_read_key ();
122               RL_UNSETSTATE(RL_STATE_MOREINPUT);
123               rl_restore_prompt ();
124               rl_clear_message ();
125               RL_UNSETSTATE(RL_STATE_NUMERICARG);
126               return (_rl_dispatch (key, _rl_keymap));
127             }
128         }
129
130       c = UNMETA (c);
131
132       if (_rl_digit_p (c))
133         {
134           rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
135           sawdigits = rl_explicit_arg = 1;
136         }
137       else if (c == '-' && rl_explicit_arg == 0)
138         {
139           rl_numeric_arg = sawminus = 1;
140           rl_arg_sign = -1;
141         }
142       else
143         {
144           /* Make M-- command equivalent to M--1 command. */
145           if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
146             rl_explicit_arg = 1;
147           rl_restore_prompt ();
148           rl_clear_message ();
149           RL_UNSETSTATE(RL_STATE_NUMERICARG);
150           return (_rl_dispatch (key, _rl_keymap));
151         }
152     }
153
154   /*NOTREACHED*/
155 }
156
157 /* Add the current digit to the argument in progress. */
158 int
159 rl_digit_argument (ignore, key)
160      int ignore, key;
161 {
162   rl_execute_next (key);
163   return (rl_digit_loop ());
164 }
165
166 /* What to do when you abort reading an argument. */
167 int
168 rl_discard_argument ()
169 {
170   rl_ding ();
171   rl_clear_message ();
172   _rl_init_argument ();
173   return 0;
174 }
175
176 /* Create a default argument. */
177 int
178 _rl_init_argument ()
179 {
180   rl_numeric_arg = rl_arg_sign = 1;
181   rl_explicit_arg = 0;
182   return 0;
183 }
184
185 /* C-u, universal argument.  Multiply the current argument by 4.
186    Read a key.  If the key has nothing to do with arguments, then
187    dispatch on it.  If the key is the abort character then abort. */
188 int
189 rl_universal_argument (count, key)
190      int count, key;
191 {
192   rl_numeric_arg *= 4;
193   return (rl_digit_loop ());
194 }
195
196 /* **************************************************************** */
197 /*                                                                  */
198 /*                      History Utilities                           */
199 /*                                                                  */
200 /* **************************************************************** */
201
202 /* We already have a history library, and that is what we use to control
203    the history features of readline.  This is our local interface to
204    the history mechanism. */
205
206 /* While we are editing the history, this is the saved
207    version of the original line. */
208 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
209
210 /* Set the history pointer back to the last entry in the history. */
211 void
212 _rl_start_using_history ()
213 {
214   using_history ();
215   if (_rl_saved_line_for_history)
216     _rl_free_history_entry (_rl_saved_line_for_history);
217
218   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
219 }
220
221 /* Free the contents (and containing structure) of a HIST_ENTRY. */
222 void
223 _rl_free_history_entry (entry)
224      HIST_ENTRY *entry;
225 {
226   if (entry == 0)
227     return;
228   if (entry->line)
229     free (entry->line);
230   free (entry);
231 }
232
233 /* Perhaps put back the current line if it has changed. */
234 int
235 rl_maybe_replace_line ()
236 {
237   HIST_ENTRY *temp;
238
239   temp = current_history ();
240   /* If the current line has changed, save the changes. */
241   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
242     {
243       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
244       free (temp->line);
245       free (temp);
246     }
247   return 0;
248 }
249
250 /* Restore the _rl_saved_line_for_history if there is one. */
251 int
252 rl_maybe_unsave_line ()
253 {
254   if (_rl_saved_line_for_history)
255     {
256       /* Can't call with `1' because rl_undo_list might point to an undo
257          list from a history entry, as in rl_replace_from_history() below. */
258       rl_replace_line (_rl_saved_line_for_history->line, 0);
259       rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
260       _rl_free_history_entry (_rl_saved_line_for_history);
261       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
262       rl_point = rl_end;        /* rl_replace_line sets rl_end */
263     }
264   else
265     rl_ding ();
266   return 0;
267 }
268
269 /* Save the current line in _rl_saved_line_for_history. */
270 int
271 rl_maybe_save_line ()
272 {
273   if (_rl_saved_line_for_history == 0)
274     {
275       _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
276       _rl_saved_line_for_history->line = savestring (rl_line_buffer);
277       _rl_saved_line_for_history->data = (char *)rl_undo_list;
278     }
279
280   return 0;
281 }
282
283 int
284 _rl_free_saved_history_line ()
285 {
286   if (_rl_saved_line_for_history)
287     {
288       _rl_free_history_entry (_rl_saved_line_for_history);
289       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
290     }
291   return 0;
292 }
293
294 static void
295 _rl_history_set_point ()
296 {
297   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
298                 ? _rl_history_saved_point
299                 : rl_end;
300   if (rl_point > rl_end)
301     rl_point = rl_end;
302
303 #if defined (VI_MODE)
304   if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
305     rl_point = 0;
306 #endif /* VI_MODE */
307
308   if (rl_editing_mode == emacs_mode)
309     rl_mark = (rl_point == rl_end ? 0 : rl_end);
310 }
311
312 void
313 rl_replace_from_history (entry, flags)
314      HIST_ENTRY *entry;
315      int flags;                 /* currently unused */
316 {
317   /* Can't call with `1' because rl_undo_list might point to an undo list
318      from a history entry, just like we're setting up here. */
319   rl_replace_line (entry->line, 0);
320   rl_undo_list = (UNDO_LIST *)entry->data;
321   rl_point = rl_end;
322   rl_mark = 0;
323
324 #if defined (VI_MODE)
325   if (rl_editing_mode == vi_mode)
326     {
327       rl_point = 0;
328       rl_mark = rl_end;
329     }
330 #endif
331 }  
332
333 /* **************************************************************** */
334 /*                                                                  */
335 /*                      History Commands                            */
336 /*                                                                  */
337 /* **************************************************************** */
338
339 /* Meta-< goes to the start of the history. */
340 int
341 rl_beginning_of_history (count, key)
342      int count, key;
343 {
344   return (rl_get_previous_history (1 + where_history (), key));
345 }
346
347 /* Meta-> goes to the end of the history.  (The current line). */
348 int
349 rl_end_of_history (count, key)
350      int count, key;
351 {
352   rl_maybe_replace_line ();
353   using_history ();
354   rl_maybe_unsave_line ();
355   return 0;
356 }
357
358 /* Move down to the next history line. */
359 int
360 rl_get_next_history (count, key)
361      int count, key;
362 {
363   HIST_ENTRY *temp;
364
365   if (count < 0)
366     return (rl_get_previous_history (-count, key));
367
368   if (count == 0)
369     return 0;
370
371   rl_maybe_replace_line ();
372
373   /* either not saved by rl_newline or at end of line, so set appropriately. */
374   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
375     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
376
377   temp = (HIST_ENTRY *)NULL;
378   while (count)
379     {
380       temp = next_history ();
381       if (!temp)
382         break;
383       --count;
384     }
385
386   if (temp == 0)
387     rl_maybe_unsave_line ();
388   else
389     {
390       rl_replace_from_history (temp, 0);
391       _rl_history_set_point ();
392     }
393   return 0;
394 }
395
396 /* Get the previous item out of our interactive history, making it the current
397    line.  If there is no previous history, just ding. */
398 int
399 rl_get_previous_history (count, key)
400      int count, key;
401 {
402   HIST_ENTRY *old_temp, *temp;
403
404   if (count < 0)
405     return (rl_get_next_history (-count, key));
406
407   if (count == 0)
408     return 0;
409
410   /* either not saved by rl_newline or at end of line, so set appropriately. */
411   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
412     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
413
414   /* If we don't have a line saved, then save this one. */
415   rl_maybe_save_line ();
416
417   /* If the current line has changed, save the changes. */
418   rl_maybe_replace_line ();
419
420   temp = old_temp = (HIST_ENTRY *)NULL;
421   while (count)
422     {
423       temp = previous_history ();
424       if (temp == 0)
425         break;
426
427       old_temp = temp;
428       --count;
429     }
430
431   /* If there was a large argument, and we moved back to the start of the
432      history, that is not an error.  So use the last value found. */
433   if (!temp && old_temp)
434     temp = old_temp;
435
436   if (temp == 0)
437     rl_ding ();
438   else
439     {
440       rl_replace_from_history (temp, 0);
441       _rl_history_set_point ();
442     }
443
444   return 0;
445 }
446
447 /* **************************************************************** */
448 /*                                                                  */
449 /*                          Editing Modes                           */
450 /*                                                                  */
451 /* **************************************************************** */
452 /* How to toggle back and forth between editing modes. */
453 int
454 rl_vi_editing_mode (count, key)
455      int count, key;
456 {
457 #if defined (VI_MODE)
458   _rl_set_insert_mode (RL_IM_INSERT, 1);        /* vi mode ignores insert mode */
459   rl_editing_mode = vi_mode;
460   rl_vi_insertion_mode (1, key);
461 #endif /* VI_MODE */
462
463   return 0;
464 }
465
466 int
467 rl_emacs_editing_mode (count, key)
468      int count, key;
469 {
470   rl_editing_mode = emacs_mode;
471   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
472   _rl_keymap = emacs_standard_keymap;
473   return 0;
474 }
475
476 /* Function for the rest of the library to use to set insert/overwrite mode. */
477 void
478 _rl_set_insert_mode (im, force)
479      int im, force;
480 {
481 #ifdef CURSOR_MODE
482   _rl_set_cursor (im, force);
483 #endif
484
485   rl_insert_mode = im;
486 }
487
488 /* Toggle overwrite mode.  A positive explicit argument selects overwrite
489    mode.  A negative or zero explicit argument selects insert mode. */
490 int
491 rl_overwrite_mode (count, key)
492      int count, key;
493 {
494   if (rl_explicit_arg == 0)
495     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
496   else if (count > 0)
497     _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
498   else
499     _rl_set_insert_mode (RL_IM_INSERT, 0);
500
501   return 0;
502 }