xref: /dflybsd-src/contrib/gdb-7/readline/misc.c (revision 16003dcfd2baa152f5dd24794ec9f36e139eaeb8)
1*6b445a62SJohn Marino /* misc.c -- miscellaneous bindable readline functions. */
2*6b445a62SJohn Marino 
3*6b445a62SJohn Marino /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
4*6b445a62SJohn Marino 
5*6b445a62SJohn Marino    This file is part of the GNU Readline Library (Readline), a library
6*6b445a62SJohn Marino    for reading lines of text with interactive input and history editing.
7*6b445a62SJohn Marino 
8*6b445a62SJohn Marino    Readline is free software: you can redistribute it and/or modify
9*6b445a62SJohn Marino    it under the terms of the GNU General Public License as published by
10*6b445a62SJohn Marino    the Free Software Foundation, either version 3 of the License, or
11*6b445a62SJohn Marino    (at your option) any later version.
12*6b445a62SJohn Marino 
13*6b445a62SJohn Marino    Readline is distributed in the hope that it will be useful,
14*6b445a62SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*6b445a62SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*6b445a62SJohn Marino    GNU General Public License for more details.
17*6b445a62SJohn Marino 
18*6b445a62SJohn Marino    You should have received a copy of the GNU General Public License
19*6b445a62SJohn Marino    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
20*6b445a62SJohn Marino */
21*6b445a62SJohn Marino 
22*6b445a62SJohn Marino #define READLINE_LIBRARY
23*6b445a62SJohn Marino 
24*6b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
25*6b445a62SJohn Marino #  include <config.h>
26*6b445a62SJohn Marino #endif
27*6b445a62SJohn Marino 
28*6b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
29*6b445a62SJohn Marino #  include <unistd.h>
30*6b445a62SJohn Marino #endif /* HAVE_UNISTD_H */
31*6b445a62SJohn Marino 
32*6b445a62SJohn Marino #if defined (HAVE_STDLIB_H)
33*6b445a62SJohn Marino #  include <stdlib.h>
34*6b445a62SJohn Marino #else
35*6b445a62SJohn Marino #  include "ansi_stdlib.h"
36*6b445a62SJohn Marino #endif /* HAVE_STDLIB_H */
37*6b445a62SJohn Marino 
38*6b445a62SJohn Marino #if defined (HAVE_LOCALE_H)
39*6b445a62SJohn Marino #  include <locale.h>
40*6b445a62SJohn Marino #endif
41*6b445a62SJohn Marino 
42*6b445a62SJohn Marino #include <stdio.h>
43*6b445a62SJohn Marino 
44*6b445a62SJohn Marino /* System-specific feature definitions and include files. */
45*6b445a62SJohn Marino #include "rldefs.h"
46*6b445a62SJohn Marino #include "rlmbutil.h"
47*6b445a62SJohn Marino 
48*6b445a62SJohn Marino /* Some standard library routines. */
49*6b445a62SJohn Marino #include "readline.h"
50*6b445a62SJohn Marino #include "history.h"
51*6b445a62SJohn Marino 
52*6b445a62SJohn Marino #include "rlprivate.h"
53*6b445a62SJohn Marino #include "rlshell.h"
54*6b445a62SJohn Marino #include "xmalloc.h"
55*6b445a62SJohn Marino 
56*6b445a62SJohn Marino static int rl_digit_loop PARAMS((void));
57*6b445a62SJohn Marino static void _rl_history_set_point PARAMS((void));
58*6b445a62SJohn Marino 
59*6b445a62SJohn Marino /* Forward declarations used in this file */
60*6b445a62SJohn Marino void _rl_free_history_entry PARAMS((HIST_ENTRY *));
61*6b445a62SJohn Marino 
62*6b445a62SJohn Marino /* If non-zero, rl_get_previous_history and rl_get_next_history attempt
63*6b445a62SJohn Marino    to preserve the value of rl_point from line to line. */
64*6b445a62SJohn Marino int _rl_history_preserve_point = 0;
65*6b445a62SJohn Marino 
66*6b445a62SJohn Marino _rl_arg_cxt _rl_argcxt;
67*6b445a62SJohn Marino 
68*6b445a62SJohn Marino /* Saved target point for when _rl_history_preserve_point is set.  Special
69*6b445a62SJohn Marino    value of -1 means that point is at the end of the line. */
70*6b445a62SJohn Marino int _rl_history_saved_point = -1;
71*6b445a62SJohn Marino 
72*6b445a62SJohn Marino /* **************************************************************** */
73*6b445a62SJohn Marino /*								    */
74*6b445a62SJohn Marino /*			Numeric Arguments			    */
75*6b445a62SJohn Marino /*								    */
76*6b445a62SJohn Marino /* **************************************************************** */
77*6b445a62SJohn Marino 
78*6b445a62SJohn Marino int
_rl_arg_overflow()79*6b445a62SJohn Marino _rl_arg_overflow ()
80*6b445a62SJohn Marino {
81*6b445a62SJohn Marino   if (rl_numeric_arg > 1000000)
82*6b445a62SJohn Marino     {
83*6b445a62SJohn Marino       _rl_argcxt = 0;
84*6b445a62SJohn Marino       rl_explicit_arg = rl_numeric_arg = 0;
85*6b445a62SJohn Marino       rl_ding ();
86*6b445a62SJohn Marino       rl_restore_prompt ();
87*6b445a62SJohn Marino       rl_clear_message ();
88*6b445a62SJohn Marino       RL_UNSETSTATE(RL_STATE_NUMERICARG);
89*6b445a62SJohn Marino       return 1;
90*6b445a62SJohn Marino     }
91*6b445a62SJohn Marino   return 0;
92*6b445a62SJohn Marino }
93*6b445a62SJohn Marino 
94*6b445a62SJohn Marino void
_rl_arg_init()95*6b445a62SJohn Marino _rl_arg_init ()
96*6b445a62SJohn Marino {
97*6b445a62SJohn Marino   rl_save_prompt ();
98*6b445a62SJohn Marino   _rl_argcxt = 0;
99*6b445a62SJohn Marino   RL_SETSTATE(RL_STATE_NUMERICARG);
100*6b445a62SJohn Marino }
101*6b445a62SJohn Marino 
102*6b445a62SJohn Marino int
_rl_arg_getchar()103*6b445a62SJohn Marino _rl_arg_getchar ()
104*6b445a62SJohn Marino {
105*6b445a62SJohn Marino   int c;
106*6b445a62SJohn Marino 
107*6b445a62SJohn Marino   rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
108*6b445a62SJohn Marino   RL_SETSTATE(RL_STATE_MOREINPUT);
109*6b445a62SJohn Marino   c = rl_read_key ();
110*6b445a62SJohn Marino   RL_UNSETSTATE(RL_STATE_MOREINPUT);
111*6b445a62SJohn Marino 
112*6b445a62SJohn Marino   return c;
113*6b445a62SJohn Marino }
114*6b445a62SJohn Marino 
115*6b445a62SJohn Marino /* Process C as part of the current numeric argument.  Return -1 if the
116*6b445a62SJohn Marino    argument should be aborted, 0 if we should not read any more chars, and
117*6b445a62SJohn Marino    1 if we should continue to read chars. */
118*6b445a62SJohn Marino int
_rl_arg_dispatch(cxt,c)119*6b445a62SJohn Marino _rl_arg_dispatch (cxt, c)
120*6b445a62SJohn Marino      _rl_arg_cxt cxt;
121*6b445a62SJohn Marino      int c;
122*6b445a62SJohn Marino {
123*6b445a62SJohn Marino   int key, r;
124*6b445a62SJohn Marino 
125*6b445a62SJohn Marino   key = c;
126*6b445a62SJohn Marino 
127*6b445a62SJohn Marino   /* If we see a key bound to `universal-argument' after seeing digits,
128*6b445a62SJohn Marino       it ends the argument but is otherwise ignored. */
129*6b445a62SJohn Marino   if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
130*6b445a62SJohn Marino     {
131*6b445a62SJohn Marino       if ((cxt & NUM_SAWDIGITS) == 0)
132*6b445a62SJohn Marino 	{
133*6b445a62SJohn Marino 	  rl_numeric_arg *= 4;
134*6b445a62SJohn Marino 	  return 1;
135*6b445a62SJohn Marino 	}
136*6b445a62SJohn Marino       else if (RL_ISSTATE (RL_STATE_CALLBACK))
137*6b445a62SJohn Marino         {
138*6b445a62SJohn Marino           _rl_argcxt |= NUM_READONE;
139*6b445a62SJohn Marino           return 0;	/* XXX */
140*6b445a62SJohn Marino         }
141*6b445a62SJohn Marino       else
142*6b445a62SJohn Marino 	{
143*6b445a62SJohn Marino 	  RL_SETSTATE(RL_STATE_MOREINPUT);
144*6b445a62SJohn Marino 	  key = rl_read_key ();
145*6b445a62SJohn Marino 	  RL_UNSETSTATE(RL_STATE_MOREINPUT);
146*6b445a62SJohn Marino 	  rl_restore_prompt ();
147*6b445a62SJohn Marino 	  rl_clear_message ();
148*6b445a62SJohn Marino 	  RL_UNSETSTATE(RL_STATE_NUMERICARG);
149*6b445a62SJohn Marino 	  if (key < 0)
150*6b445a62SJohn Marino 	    return -1;
151*6b445a62SJohn Marino 	  return (_rl_dispatch (key, _rl_keymap));
152*6b445a62SJohn Marino 	}
153*6b445a62SJohn Marino     }
154*6b445a62SJohn Marino 
155*6b445a62SJohn Marino   c = UNMETA (c);
156*6b445a62SJohn Marino 
157*6b445a62SJohn Marino   if (_rl_digit_p (c))
158*6b445a62SJohn Marino     {
159*6b445a62SJohn Marino       r = _rl_digit_value (c);
160*6b445a62SJohn Marino       rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
161*6b445a62SJohn Marino       rl_explicit_arg = 1;
162*6b445a62SJohn Marino       _rl_argcxt |= NUM_SAWDIGITS;
163*6b445a62SJohn Marino     }
164*6b445a62SJohn Marino   else if (c == '-' && rl_explicit_arg == 0)
165*6b445a62SJohn Marino     {
166*6b445a62SJohn Marino       rl_numeric_arg = 1;
167*6b445a62SJohn Marino       _rl_argcxt |= NUM_SAWMINUS;
168*6b445a62SJohn Marino       rl_arg_sign = -1;
169*6b445a62SJohn Marino     }
170*6b445a62SJohn Marino   else
171*6b445a62SJohn Marino     {
172*6b445a62SJohn Marino       /* Make M-- command equivalent to M--1 command. */
173*6b445a62SJohn Marino       if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
174*6b445a62SJohn Marino 	rl_explicit_arg = 1;
175*6b445a62SJohn Marino       rl_restore_prompt ();
176*6b445a62SJohn Marino       rl_clear_message ();
177*6b445a62SJohn Marino       RL_UNSETSTATE(RL_STATE_NUMERICARG);
178*6b445a62SJohn Marino 
179*6b445a62SJohn Marino       r = _rl_dispatch (key, _rl_keymap);
180*6b445a62SJohn Marino       if (RL_ISSTATE (RL_STATE_CALLBACK))
181*6b445a62SJohn Marino 	{
182*6b445a62SJohn Marino 	  /* At worst, this will cause an extra redisplay.  Otherwise,
183*6b445a62SJohn Marino 	     we have to wait until the next character comes in. */
184*6b445a62SJohn Marino 	  if (rl_done == 0)
185*6b445a62SJohn Marino 	    (*rl_redisplay_function) ();
186*6b445a62SJohn Marino 	  r = 0;
187*6b445a62SJohn Marino 	}
188*6b445a62SJohn Marino       return r;
189*6b445a62SJohn Marino     }
190*6b445a62SJohn Marino 
191*6b445a62SJohn Marino   return 1;
192*6b445a62SJohn Marino }
193*6b445a62SJohn Marino 
194*6b445a62SJohn Marino /* Handle C-u style numeric args, as well as M--, and M-digits. */
195*6b445a62SJohn Marino static int
rl_digit_loop()196*6b445a62SJohn Marino rl_digit_loop ()
197*6b445a62SJohn Marino {
198*6b445a62SJohn Marino   int c, r;
199*6b445a62SJohn Marino 
200*6b445a62SJohn Marino   while (1)
201*6b445a62SJohn Marino     {
202*6b445a62SJohn Marino       if (_rl_arg_overflow ())
203*6b445a62SJohn Marino 	return 1;
204*6b445a62SJohn Marino 
205*6b445a62SJohn Marino       c = _rl_arg_getchar ();
206*6b445a62SJohn Marino 
207*6b445a62SJohn Marino       if (c < 0)
208*6b445a62SJohn Marino 	{
209*6b445a62SJohn Marino 	  _rl_abort_internal ();
210*6b445a62SJohn Marino 	  return -1;
211*6b445a62SJohn Marino 	}
212*6b445a62SJohn Marino 
213*6b445a62SJohn Marino       r = _rl_arg_dispatch (_rl_argcxt, c);
214*6b445a62SJohn Marino       if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
215*6b445a62SJohn Marino         break;
216*6b445a62SJohn Marino     }
217*6b445a62SJohn Marino 
218*6b445a62SJohn Marino   return r;
219*6b445a62SJohn Marino }
220*6b445a62SJohn Marino 
221*6b445a62SJohn Marino /* Create a default argument. */
222*6b445a62SJohn Marino void
_rl_reset_argument()223*6b445a62SJohn Marino _rl_reset_argument ()
224*6b445a62SJohn Marino {
225*6b445a62SJohn Marino   rl_numeric_arg = rl_arg_sign = 1;
226*6b445a62SJohn Marino   rl_explicit_arg = 0;
227*6b445a62SJohn Marino   _rl_argcxt = 0;
228*6b445a62SJohn Marino }
229*6b445a62SJohn Marino 
230*6b445a62SJohn Marino /* Start a numeric argument with initial value KEY */
231*6b445a62SJohn Marino int
rl_digit_argument(ignore,key)232*6b445a62SJohn Marino rl_digit_argument (ignore, key)
233*6b445a62SJohn Marino      int ignore, key;
234*6b445a62SJohn Marino {
235*6b445a62SJohn Marino   _rl_arg_init ();
236*6b445a62SJohn Marino   if (RL_ISSTATE (RL_STATE_CALLBACK))
237*6b445a62SJohn Marino     {
238*6b445a62SJohn Marino       _rl_arg_dispatch (_rl_argcxt, key);
239*6b445a62SJohn Marino       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
240*6b445a62SJohn Marino       return 0;
241*6b445a62SJohn Marino     }
242*6b445a62SJohn Marino   else
243*6b445a62SJohn Marino     {
244*6b445a62SJohn Marino       rl_execute_next (key);
245*6b445a62SJohn Marino       return (rl_digit_loop ());
246*6b445a62SJohn Marino     }
247*6b445a62SJohn Marino }
248*6b445a62SJohn Marino 
249*6b445a62SJohn Marino /* C-u, universal argument.  Multiply the current argument by 4.
250*6b445a62SJohn Marino    Read a key.  If the key has nothing to do with arguments, then
251*6b445a62SJohn Marino    dispatch on it.  If the key is the abort character then abort. */
252*6b445a62SJohn Marino int
rl_universal_argument(count,key)253*6b445a62SJohn Marino rl_universal_argument (count, key)
254*6b445a62SJohn Marino      int count, key;
255*6b445a62SJohn Marino {
256*6b445a62SJohn Marino   _rl_arg_init ();
257*6b445a62SJohn Marino   rl_numeric_arg *= 4;
258*6b445a62SJohn Marino 
259*6b445a62SJohn Marino   return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
260*6b445a62SJohn Marino }
261*6b445a62SJohn Marino 
262*6b445a62SJohn Marino int
_rl_arg_callback(cxt)263*6b445a62SJohn Marino _rl_arg_callback (cxt)
264*6b445a62SJohn Marino      _rl_arg_cxt cxt;
265*6b445a62SJohn Marino {
266*6b445a62SJohn Marino   int c, r;
267*6b445a62SJohn Marino 
268*6b445a62SJohn Marino   c = _rl_arg_getchar ();
269*6b445a62SJohn Marino 
270*6b445a62SJohn Marino   if (_rl_argcxt & NUM_READONE)
271*6b445a62SJohn Marino     {
272*6b445a62SJohn Marino       _rl_argcxt &= ~NUM_READONE;
273*6b445a62SJohn Marino       rl_restore_prompt ();
274*6b445a62SJohn Marino       rl_clear_message ();
275*6b445a62SJohn Marino       RL_UNSETSTATE(RL_STATE_NUMERICARG);
276*6b445a62SJohn Marino       rl_execute_next (c);
277*6b445a62SJohn Marino       return 0;
278*6b445a62SJohn Marino     }
279*6b445a62SJohn Marino 
280*6b445a62SJohn Marino   r = _rl_arg_dispatch (cxt, c);
281*6b445a62SJohn Marino   return (r != 1);
282*6b445a62SJohn Marino }
283*6b445a62SJohn Marino 
284*6b445a62SJohn Marino /* What to do when you abort reading an argument. */
285*6b445a62SJohn Marino int
rl_discard_argument()286*6b445a62SJohn Marino rl_discard_argument ()
287*6b445a62SJohn Marino {
288*6b445a62SJohn Marino   rl_ding ();
289*6b445a62SJohn Marino   rl_clear_message ();
290*6b445a62SJohn Marino   _rl_reset_argument ();
291*6b445a62SJohn Marino 
292*6b445a62SJohn Marino   return 0;
293*6b445a62SJohn Marino }
294*6b445a62SJohn Marino 
295*6b445a62SJohn Marino /* **************************************************************** */
296*6b445a62SJohn Marino /*								    */
297*6b445a62SJohn Marino /*			History Utilities			    */
298*6b445a62SJohn Marino /*								    */
299*6b445a62SJohn Marino /* **************************************************************** */
300*6b445a62SJohn Marino 
301*6b445a62SJohn Marino /* We already have a history library, and that is what we use to control
302*6b445a62SJohn Marino    the history features of readline.  This is our local interface to
303*6b445a62SJohn Marino    the history mechanism. */
304*6b445a62SJohn Marino 
305*6b445a62SJohn Marino /* While we are editing the history, this is the saved
306*6b445a62SJohn Marino    version of the original line. */
307*6b445a62SJohn Marino HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
308*6b445a62SJohn Marino 
309*6b445a62SJohn Marino /* Set the history pointer back to the last entry in the history. */
310*6b445a62SJohn Marino void
_rl_start_using_history()311*6b445a62SJohn Marino _rl_start_using_history ()
312*6b445a62SJohn Marino {
313*6b445a62SJohn Marino   using_history ();
314*6b445a62SJohn Marino   if (_rl_saved_line_for_history)
315*6b445a62SJohn Marino     _rl_free_history_entry (_rl_saved_line_for_history);
316*6b445a62SJohn Marino 
317*6b445a62SJohn Marino   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
318*6b445a62SJohn Marino }
319*6b445a62SJohn Marino 
320*6b445a62SJohn Marino /* Free the contents (and containing structure) of a HIST_ENTRY. */
321*6b445a62SJohn Marino void
_rl_free_history_entry(entry)322*6b445a62SJohn Marino _rl_free_history_entry (entry)
323*6b445a62SJohn Marino      HIST_ENTRY *entry;
324*6b445a62SJohn Marino {
325*6b445a62SJohn Marino   if (entry == 0)
326*6b445a62SJohn Marino     return;
327*6b445a62SJohn Marino 
328*6b445a62SJohn Marino   FREE (entry->line);
329*6b445a62SJohn Marino   FREE (entry->timestamp);
330*6b445a62SJohn Marino 
331*6b445a62SJohn Marino   xfree (entry);
332*6b445a62SJohn Marino }
333*6b445a62SJohn Marino 
334*6b445a62SJohn Marino /* Perhaps put back the current line if it has changed. */
335*6b445a62SJohn Marino int
rl_maybe_replace_line()336*6b445a62SJohn Marino rl_maybe_replace_line ()
337*6b445a62SJohn Marino {
338*6b445a62SJohn Marino   HIST_ENTRY *temp;
339*6b445a62SJohn Marino 
340*6b445a62SJohn Marino   temp = current_history ();
341*6b445a62SJohn Marino   /* If the current line has changed, save the changes. */
342*6b445a62SJohn Marino   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
343*6b445a62SJohn Marino     {
344*6b445a62SJohn Marino       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
345*6b445a62SJohn Marino       xfree (temp->line);
346*6b445a62SJohn Marino       FREE (temp->timestamp);
347*6b445a62SJohn Marino       xfree (temp);
348*6b445a62SJohn Marino     }
349*6b445a62SJohn Marino   return 0;
350*6b445a62SJohn Marino }
351*6b445a62SJohn Marino 
352*6b445a62SJohn Marino /* Restore the _rl_saved_line_for_history if there is one. */
353*6b445a62SJohn Marino int
rl_maybe_unsave_line()354*6b445a62SJohn Marino rl_maybe_unsave_line ()
355*6b445a62SJohn Marino {
356*6b445a62SJohn Marino   if (_rl_saved_line_for_history)
357*6b445a62SJohn Marino     {
358*6b445a62SJohn Marino       /* Can't call with `1' because rl_undo_list might point to an undo
359*6b445a62SJohn Marino 	 list from a history entry, as in rl_replace_from_history() below. */
360*6b445a62SJohn Marino       rl_replace_line (_rl_saved_line_for_history->line, 0);
361*6b445a62SJohn Marino       rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
362*6b445a62SJohn Marino       _rl_free_history_entry (_rl_saved_line_for_history);
363*6b445a62SJohn Marino       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
364*6b445a62SJohn Marino       rl_point = rl_end;	/* rl_replace_line sets rl_end */
365*6b445a62SJohn Marino     }
366*6b445a62SJohn Marino   else
367*6b445a62SJohn Marino     rl_ding ();
368*6b445a62SJohn Marino   return 0;
369*6b445a62SJohn Marino }
370*6b445a62SJohn Marino 
371*6b445a62SJohn Marino /* Save the current line in _rl_saved_line_for_history. */
372*6b445a62SJohn Marino int
rl_maybe_save_line()373*6b445a62SJohn Marino rl_maybe_save_line ()
374*6b445a62SJohn Marino {
375*6b445a62SJohn Marino   if (_rl_saved_line_for_history == 0)
376*6b445a62SJohn Marino     {
377*6b445a62SJohn Marino       _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
378*6b445a62SJohn Marino       _rl_saved_line_for_history->line = savestring (rl_line_buffer);
379*6b445a62SJohn Marino       _rl_saved_line_for_history->timestamp = (char *)NULL;
380*6b445a62SJohn Marino       _rl_saved_line_for_history->data = (char *)rl_undo_list;
381*6b445a62SJohn Marino     }
382*6b445a62SJohn Marino 
383*6b445a62SJohn Marino   return 0;
384*6b445a62SJohn Marino }
385*6b445a62SJohn Marino 
386*6b445a62SJohn Marino int
_rl_free_saved_history_line()387*6b445a62SJohn Marino _rl_free_saved_history_line ()
388*6b445a62SJohn Marino {
389*6b445a62SJohn Marino   if (_rl_saved_line_for_history)
390*6b445a62SJohn Marino     {
391*6b445a62SJohn Marino       _rl_free_history_entry (_rl_saved_line_for_history);
392*6b445a62SJohn Marino       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
393*6b445a62SJohn Marino     }
394*6b445a62SJohn Marino   return 0;
395*6b445a62SJohn Marino }
396*6b445a62SJohn Marino 
397*6b445a62SJohn Marino static void
_rl_history_set_point()398*6b445a62SJohn Marino _rl_history_set_point ()
399*6b445a62SJohn Marino {
400*6b445a62SJohn Marino   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
401*6b445a62SJohn Marino 		? _rl_history_saved_point
402*6b445a62SJohn Marino 		: rl_end;
403*6b445a62SJohn Marino   if (rl_point > rl_end)
404*6b445a62SJohn Marino     rl_point = rl_end;
405*6b445a62SJohn Marino 
406*6b445a62SJohn Marino #if defined (VI_MODE)
407*6b445a62SJohn Marino   if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
408*6b445a62SJohn Marino     rl_point = 0;
409*6b445a62SJohn Marino #endif /* VI_MODE */
410*6b445a62SJohn Marino 
411*6b445a62SJohn Marino   if (rl_editing_mode == emacs_mode)
412*6b445a62SJohn Marino     rl_mark = (rl_point == rl_end ? 0 : rl_end);
413*6b445a62SJohn Marino }
414*6b445a62SJohn Marino 
415*6b445a62SJohn Marino void
rl_replace_from_history(entry,flags)416*6b445a62SJohn Marino rl_replace_from_history (entry, flags)
417*6b445a62SJohn Marino      HIST_ENTRY *entry;
418*6b445a62SJohn Marino      int flags;			/* currently unused */
419*6b445a62SJohn Marino {
420*6b445a62SJohn Marino   /* Can't call with `1' because rl_undo_list might point to an undo list
421*6b445a62SJohn Marino      from a history entry, just like we're setting up here. */
422*6b445a62SJohn Marino   rl_replace_line (entry->line, 0);
423*6b445a62SJohn Marino   rl_undo_list = (UNDO_LIST *)entry->data;
424*6b445a62SJohn Marino   rl_point = rl_end;
425*6b445a62SJohn Marino   rl_mark = 0;
426*6b445a62SJohn Marino 
427*6b445a62SJohn Marino #if defined (VI_MODE)
428*6b445a62SJohn Marino   if (rl_editing_mode == vi_mode)
429*6b445a62SJohn Marino     {
430*6b445a62SJohn Marino       rl_point = 0;
431*6b445a62SJohn Marino       rl_mark = rl_end;
432*6b445a62SJohn Marino     }
433*6b445a62SJohn Marino #endif
434*6b445a62SJohn Marino }
435*6b445a62SJohn Marino 
436*6b445a62SJohn Marino /* Process and free undo lists attached to each history entry prior to the
437*6b445a62SJohn Marino    current entry, inclusive, reverting each line to its saved state.  This
438*6b445a62SJohn Marino    is destructive, and state about the current line is lost.  This is not
439*6b445a62SJohn Marino    intended to be called while actively editing, and the current line is
440*6b445a62SJohn Marino    not assumed to have been added to the history list. */
441*6b445a62SJohn Marino void
_rl_revert_all_lines()442*6b445a62SJohn Marino _rl_revert_all_lines ()
443*6b445a62SJohn Marino {
444*6b445a62SJohn Marino   int hpos;
445*6b445a62SJohn Marino   HIST_ENTRY *entry;
446*6b445a62SJohn Marino   UNDO_LIST *ul, *saved_undo_list;
447*6b445a62SJohn Marino   char *lbuf;
448*6b445a62SJohn Marino 
449*6b445a62SJohn Marino   lbuf = savestring (rl_line_buffer);
450*6b445a62SJohn Marino   saved_undo_list = rl_undo_list;
451*6b445a62SJohn Marino   hpos = where_history ();
452*6b445a62SJohn Marino 
453*6b445a62SJohn Marino   entry = (hpos == history_length) ? previous_history () : current_history ();
454*6b445a62SJohn Marino   while (entry)
455*6b445a62SJohn Marino     {
456*6b445a62SJohn Marino       if (ul = (UNDO_LIST *)entry->data)
457*6b445a62SJohn Marino 	{
458*6b445a62SJohn Marino 	  if (ul == saved_undo_list)
459*6b445a62SJohn Marino 	    saved_undo_list = 0;
460*6b445a62SJohn Marino 	  /* Set up rl_line_buffer and other variables from history entry */
461*6b445a62SJohn Marino 	  rl_replace_from_history (entry, 0);	/* entry->line is now current */
462*6b445a62SJohn Marino 	  /* Undo all changes to this history entry */
463*6b445a62SJohn Marino 	  while (rl_undo_list)
464*6b445a62SJohn Marino 	    rl_do_undo ();
465*6b445a62SJohn Marino 	  /* And copy the reverted line back to the history entry, preserving
466*6b445a62SJohn Marino 	     the timestamp. */
467*6b445a62SJohn Marino 	  FREE (entry->line);
468*6b445a62SJohn Marino 	  entry->line = savestring (rl_line_buffer);
469*6b445a62SJohn Marino 	  entry->data = 0;
470*6b445a62SJohn Marino 	}
471*6b445a62SJohn Marino       entry = previous_history ();
472*6b445a62SJohn Marino     }
473*6b445a62SJohn Marino 
474*6b445a62SJohn Marino   /* Restore history state */
475*6b445a62SJohn Marino   rl_undo_list = saved_undo_list;	/* may have been set to null */
476*6b445a62SJohn Marino   history_set_pos (hpos);
477*6b445a62SJohn Marino 
478*6b445a62SJohn Marino   /* reset the line buffer */
479*6b445a62SJohn Marino   rl_replace_line (lbuf, 0);
480*6b445a62SJohn Marino   _rl_set_the_line ();
481*6b445a62SJohn Marino 
482*6b445a62SJohn Marino   /* and clean up */
483*6b445a62SJohn Marino   xfree (lbuf);
484*6b445a62SJohn Marino }
485*6b445a62SJohn Marino 
486*6b445a62SJohn Marino /* **************************************************************** */
487*6b445a62SJohn Marino /*								    */
488*6b445a62SJohn Marino /*			History Commands			    */
489*6b445a62SJohn Marino /*								    */
490*6b445a62SJohn Marino /* **************************************************************** */
491*6b445a62SJohn Marino 
492*6b445a62SJohn Marino /* Meta-< goes to the start of the history. */
493*6b445a62SJohn Marino int
rl_beginning_of_history(count,key)494*6b445a62SJohn Marino rl_beginning_of_history (count, key)
495*6b445a62SJohn Marino      int count, key;
496*6b445a62SJohn Marino {
497*6b445a62SJohn Marino   return (rl_get_previous_history (1 + where_history (), key));
498*6b445a62SJohn Marino }
499*6b445a62SJohn Marino 
500*6b445a62SJohn Marino /* Meta-> goes to the end of the history.  (The current line). */
501*6b445a62SJohn Marino int
rl_end_of_history(count,key)502*6b445a62SJohn Marino rl_end_of_history (count, key)
503*6b445a62SJohn Marino      int count, key;
504*6b445a62SJohn Marino {
505*6b445a62SJohn Marino   rl_maybe_replace_line ();
506*6b445a62SJohn Marino   using_history ();
507*6b445a62SJohn Marino   rl_maybe_unsave_line ();
508*6b445a62SJohn Marino   return 0;
509*6b445a62SJohn Marino }
510*6b445a62SJohn Marino 
511*6b445a62SJohn Marino /* Move down to the next history line. */
512*6b445a62SJohn Marino int
rl_get_next_history(count,key)513*6b445a62SJohn Marino rl_get_next_history (count, key)
514*6b445a62SJohn Marino      int count, key;
515*6b445a62SJohn Marino {
516*6b445a62SJohn Marino   HIST_ENTRY *temp;
517*6b445a62SJohn Marino 
518*6b445a62SJohn Marino   if (count < 0)
519*6b445a62SJohn Marino     return (rl_get_previous_history (-count, key));
520*6b445a62SJohn Marino 
521*6b445a62SJohn Marino   if (count == 0)
522*6b445a62SJohn Marino     return 0;
523*6b445a62SJohn Marino 
524*6b445a62SJohn Marino   rl_maybe_replace_line ();
525*6b445a62SJohn Marino 
526*6b445a62SJohn Marino   /* either not saved by rl_newline or at end of line, so set appropriately. */
527*6b445a62SJohn Marino   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
528*6b445a62SJohn Marino     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
529*6b445a62SJohn Marino 
530*6b445a62SJohn Marino   temp = (HIST_ENTRY *)NULL;
531*6b445a62SJohn Marino   while (count)
532*6b445a62SJohn Marino     {
533*6b445a62SJohn Marino       temp = next_history ();
534*6b445a62SJohn Marino       if (!temp)
535*6b445a62SJohn Marino 	break;
536*6b445a62SJohn Marino       --count;
537*6b445a62SJohn Marino     }
538*6b445a62SJohn Marino 
539*6b445a62SJohn Marino   if (temp == 0)
540*6b445a62SJohn Marino     rl_maybe_unsave_line ();
541*6b445a62SJohn Marino   else
542*6b445a62SJohn Marino     {
543*6b445a62SJohn Marino       rl_replace_from_history (temp, 0);
544*6b445a62SJohn Marino       _rl_history_set_point ();
545*6b445a62SJohn Marino     }
546*6b445a62SJohn Marino   return 0;
547*6b445a62SJohn Marino }
548*6b445a62SJohn Marino 
549*6b445a62SJohn Marino /* Get the previous item out of our interactive history, making it the current
550*6b445a62SJohn Marino    line.  If there is no previous history, just ding. */
551*6b445a62SJohn Marino int
rl_get_previous_history(count,key)552*6b445a62SJohn Marino rl_get_previous_history (count, key)
553*6b445a62SJohn Marino      int count, key;
554*6b445a62SJohn Marino {
555*6b445a62SJohn Marino   HIST_ENTRY *old_temp, *temp;
556*6b445a62SJohn Marino 
557*6b445a62SJohn Marino   if (count < 0)
558*6b445a62SJohn Marino     return (rl_get_next_history (-count, key));
559*6b445a62SJohn Marino 
560*6b445a62SJohn Marino   if (count == 0)
561*6b445a62SJohn Marino     return 0;
562*6b445a62SJohn Marino 
563*6b445a62SJohn Marino   /* either not saved by rl_newline or at end of line, so set appropriately. */
564*6b445a62SJohn Marino   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
565*6b445a62SJohn Marino     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
566*6b445a62SJohn Marino 
567*6b445a62SJohn Marino   /* If we don't have a line saved, then save this one. */
568*6b445a62SJohn Marino   rl_maybe_save_line ();
569*6b445a62SJohn Marino 
570*6b445a62SJohn Marino   /* If the current line has changed, save the changes. */
571*6b445a62SJohn Marino   rl_maybe_replace_line ();
572*6b445a62SJohn Marino 
573*6b445a62SJohn Marino   temp = old_temp = (HIST_ENTRY *)NULL;
574*6b445a62SJohn Marino   while (count)
575*6b445a62SJohn Marino     {
576*6b445a62SJohn Marino       temp = previous_history ();
577*6b445a62SJohn Marino       if (temp == 0)
578*6b445a62SJohn Marino 	break;
579*6b445a62SJohn Marino 
580*6b445a62SJohn Marino       old_temp = temp;
581*6b445a62SJohn Marino       --count;
582*6b445a62SJohn Marino     }
583*6b445a62SJohn Marino 
584*6b445a62SJohn Marino   /* If there was a large argument, and we moved back to the start of the
585*6b445a62SJohn Marino      history, that is not an error.  So use the last value found. */
586*6b445a62SJohn Marino   if (!temp && old_temp)
587*6b445a62SJohn Marino     temp = old_temp;
588*6b445a62SJohn Marino 
589*6b445a62SJohn Marino   if (temp == 0)
590*6b445a62SJohn Marino     rl_ding ();
591*6b445a62SJohn Marino   else
592*6b445a62SJohn Marino     {
593*6b445a62SJohn Marino       rl_replace_from_history (temp, 0);
594*6b445a62SJohn Marino       _rl_history_set_point ();
595*6b445a62SJohn Marino     }
596*6b445a62SJohn Marino 
597*6b445a62SJohn Marino   return 0;
598*6b445a62SJohn Marino }
599*6b445a62SJohn Marino 
600*6b445a62SJohn Marino /* **************************************************************** */
601*6b445a62SJohn Marino /*								    */
602*6b445a62SJohn Marino /*			    Editing Modes			    */
603*6b445a62SJohn Marino /*								    */
604*6b445a62SJohn Marino /* **************************************************************** */
605*6b445a62SJohn Marino /* How to toggle back and forth between editing modes. */
606*6b445a62SJohn Marino int
rl_vi_editing_mode(count,key)607*6b445a62SJohn Marino rl_vi_editing_mode (count, key)
608*6b445a62SJohn Marino      int count, key;
609*6b445a62SJohn Marino {
610*6b445a62SJohn Marino #if defined (VI_MODE)
611*6b445a62SJohn Marino   _rl_set_insert_mode (RL_IM_INSERT, 1);	/* vi mode ignores insert mode */
612*6b445a62SJohn Marino   rl_editing_mode = vi_mode;
613*6b445a62SJohn Marino   rl_vi_insert_mode (1, key);
614*6b445a62SJohn Marino #endif /* VI_MODE */
615*6b445a62SJohn Marino 
616*6b445a62SJohn Marino   return 0;
617*6b445a62SJohn Marino }
618*6b445a62SJohn Marino 
619*6b445a62SJohn Marino int
rl_emacs_editing_mode(count,key)620*6b445a62SJohn Marino rl_emacs_editing_mode (count, key)
621*6b445a62SJohn Marino      int count, key;
622*6b445a62SJohn Marino {
623*6b445a62SJohn Marino   rl_editing_mode = emacs_mode;
624*6b445a62SJohn Marino   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
625*6b445a62SJohn Marino   _rl_keymap = emacs_standard_keymap;
626*6b445a62SJohn Marino   return 0;
627*6b445a62SJohn Marino }
628*6b445a62SJohn Marino 
629*6b445a62SJohn Marino /* Function for the rest of the library to use to set insert/overwrite mode. */
630*6b445a62SJohn Marino void
_rl_set_insert_mode(im,force)631*6b445a62SJohn Marino _rl_set_insert_mode (im, force)
632*6b445a62SJohn Marino      int im, force;
633*6b445a62SJohn Marino {
634*6b445a62SJohn Marino #ifdef CURSOR_MODE
635*6b445a62SJohn Marino   _rl_set_cursor (im, force);
636*6b445a62SJohn Marino #endif
637*6b445a62SJohn Marino 
638*6b445a62SJohn Marino   rl_insert_mode = im;
639*6b445a62SJohn Marino }
640*6b445a62SJohn Marino 
641*6b445a62SJohn Marino /* Toggle overwrite mode.  A positive explicit argument selects overwrite
642*6b445a62SJohn Marino    mode.  A negative or zero explicit argument selects insert mode. */
643*6b445a62SJohn Marino int
rl_overwrite_mode(count,key)644*6b445a62SJohn Marino rl_overwrite_mode (count, key)
645*6b445a62SJohn Marino      int count, key;
646*6b445a62SJohn Marino {
647*6b445a62SJohn Marino   if (rl_explicit_arg == 0)
648*6b445a62SJohn Marino     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
649*6b445a62SJohn Marino   else if (count > 0)
650*6b445a62SJohn Marino     _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
651*6b445a62SJohn Marino   else
652*6b445a62SJohn Marino     _rl_set_insert_mode (RL_IM_INSERT, 0);
653*6b445a62SJohn Marino 
654*6b445a62SJohn Marino   return 0;
655*6b445a62SJohn Marino }
656