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