misc.c revision 165670
1119610Sache/* misc.c -- miscellaneous bindable readline functions. */
2119610Sache
3157184Sache/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
4119610Sache
5119610Sache   This file is part of the GNU Readline Library, a library for
6119610Sache   reading lines of text with interactive input and history editing.
7119610Sache
8119610Sache   The GNU Readline Library is free software; you can redistribute it
9119610Sache   and/or modify it under the terms of the GNU General Public License
10119610Sache   as published by the Free Software Foundation; either version 2, or
11119610Sache   (at your option) any later version.
12119610Sache
13119610Sache   The GNU Readline Library is distributed in the hope that it will be
14119610Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15119610Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16119610Sache   GNU General Public License for more details.
17119610Sache
18119610Sache   The GNU General Public License is often shipped with GNU software, and
19119610Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
20119610Sache   have a copy of the license, write to the Free Software Foundation,
21119610Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22119610Sache#define READLINE_LIBRARY
23119610Sache
24119610Sache#if defined (HAVE_CONFIG_H)
25119610Sache#  include <config.h>
26119610Sache#endif
27119610Sache
28119610Sache#if defined (HAVE_UNISTD_H)
29119610Sache#  include <unistd.h>
30119610Sache#endif /* HAVE_UNISTD_H */
31119610Sache
32119610Sache#if defined (HAVE_STDLIB_H)
33119610Sache#  include <stdlib.h>
34119610Sache#else
35119610Sache#  include "ansi_stdlib.h"
36119610Sache#endif /* HAVE_STDLIB_H */
37119610Sache
38119610Sache#if defined (HAVE_LOCALE_H)
39119610Sache#  include <locale.h>
40119610Sache#endif
41119610Sache
42119610Sache#include <stdio.h>
43119610Sache
44119610Sache/* System-specific feature definitions and include files. */
45119610Sache#include "rldefs.h"
46119610Sache#include "rlmbutil.h"
47119610Sache
48119610Sache/* Some standard library routines. */
49119610Sache#include "readline.h"
50119610Sache#include "history.h"
51119610Sache
52119610Sache#include "rlprivate.h"
53119610Sache#include "rlshell.h"
54119610Sache#include "xmalloc.h"
55119610Sache
56119610Sachestatic int rl_digit_loop PARAMS((void));
57119610Sachestatic void _rl_history_set_point PARAMS((void));
58119610Sache
59119610Sache/* Forward declarations used in this file */
60119610Sachevoid _rl_free_history_entry PARAMS((HIST_ENTRY *));
61119610Sache
62119610Sache/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
63119610Sache   to preserve the value of rl_point from line to line. */
64119610Sacheint _rl_history_preserve_point = 0;
65119610Sache
66157184Sache_rl_arg_cxt _rl_argcxt;
67157184Sache
68119610Sache/* Saved target point for when _rl_history_preserve_point is set.  Special
69119610Sache   value of -1 means that point is at the end of the line. */
70119610Sacheint _rl_history_saved_point = -1;
71119610Sache
72119610Sache/* **************************************************************** */
73119610Sache/*								    */
74119610Sache/*			Numeric Arguments			    */
75119610Sache/*								    */
76119610Sache/* **************************************************************** */
77119610Sache
78157184Sacheint
79157184Sache_rl_arg_overflow ()
80119610Sache{
81157184Sache  if (rl_numeric_arg > 1000000)
82157184Sache    {
83157184Sache      _rl_argcxt = 0;
84157184Sache      rl_explicit_arg = rl_numeric_arg = 0;
85157184Sache      rl_ding ();
86157184Sache      rl_restore_prompt ();
87157184Sache      rl_clear_message ();
88157184Sache      RL_UNSETSTATE(RL_STATE_NUMERICARG);
89157184Sache      return 1;
90157184Sache    }
91157184Sache  return 0;
92157184Sache}
93119610Sache
94157184Sachevoid
95157184Sache_rl_arg_init ()
96157184Sache{
97119610Sache  rl_save_prompt ();
98157184Sache  _rl_argcxt = 0;
99119610Sache  RL_SETSTATE(RL_STATE_NUMERICARG);
100157184Sache}
101119610Sache
102157184Sacheint
103157184Sache_rl_arg_getchar ()
104157184Sache{
105157184Sache  int c;
106119610Sache
107157184Sache  rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
108157184Sache  RL_SETSTATE(RL_STATE_MOREINPUT);
109157184Sache  c = rl_read_key ();
110157184Sache  RL_UNSETSTATE(RL_STATE_MOREINPUT);
111119610Sache
112157184Sache  return c;
113157184Sache}
114119610Sache
115157184Sache/* Process C as part of the current numeric argument.  Return -1 if the
116157184Sache   argument should be aborted, 0 if we should not read any more chars, and
117157184Sache   1 if we should continue to read chars. */
118157184Sacheint
119157184Sache_rl_arg_dispatch (cxt, c)
120157184Sache     _rl_arg_cxt cxt;
121157184Sache     int c;
122157184Sache{
123157184Sache  int key, r;
124157184Sache
125157184Sache  key = c;
126157184Sache
127157184Sache  /* If we see a key bound to `universal-argument' after seeing digits,
128157184Sache      it ends the argument but is otherwise ignored. */
129157184Sache  if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
130157184Sache    {
131157184Sache      if ((cxt & NUM_SAWDIGITS) == 0)
132119610Sache	{
133157184Sache	  rl_numeric_arg *= 4;
134157184Sache	  return 1;
135119610Sache	}
136157184Sache      else if (RL_ISSTATE (RL_STATE_CALLBACK))
137157184Sache        {
138157184Sache          _rl_argcxt |= NUM_READONE;
139157184Sache          return 0;	/* XXX */
140157184Sache        }
141119610Sache      else
142119610Sache	{
143157184Sache	  RL_SETSTATE(RL_STATE_MOREINPUT);
144157184Sache	  key = rl_read_key ();
145157184Sache	  RL_UNSETSTATE(RL_STATE_MOREINPUT);
146119610Sache	  rl_restore_prompt ();
147119610Sache	  rl_clear_message ();
148119610Sache	  RL_UNSETSTATE(RL_STATE_NUMERICARG);
149119610Sache	  return (_rl_dispatch (key, _rl_keymap));
150119610Sache	}
151119610Sache    }
152119610Sache
153157184Sache  c = UNMETA (c);
154157184Sache
155157184Sache  if (_rl_digit_p (c))
156157184Sache    {
157157184Sache      r = _rl_digit_value (c);
158157184Sache      rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
159157184Sache      rl_explicit_arg = 1;
160157184Sache      _rl_argcxt |= NUM_SAWDIGITS;
161157184Sache    }
162157184Sache  else if (c == '-' && rl_explicit_arg == 0)
163157184Sache    {
164157184Sache      rl_numeric_arg = 1;
165157184Sache      _rl_argcxt |= NUM_SAWMINUS;
166157184Sache      rl_arg_sign = -1;
167157184Sache    }
168157184Sache  else
169157184Sache    {
170157184Sache      /* Make M-- command equivalent to M--1 command. */
171157184Sache      if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
172157184Sache	rl_explicit_arg = 1;
173157184Sache      rl_restore_prompt ();
174157184Sache      rl_clear_message ();
175157184Sache      RL_UNSETSTATE(RL_STATE_NUMERICARG);
176157184Sache
177157184Sache      r = _rl_dispatch (key, _rl_keymap);
178157184Sache      if (RL_ISSTATE (RL_STATE_CALLBACK))
179157184Sache	{
180157184Sache	  /* At worst, this will cause an extra redisplay.  Otherwise,
181157184Sache	     we have to wait until the next character comes in. */
182157184Sache	  if (rl_done == 0)
183157184Sache	    (*rl_redisplay_function) ();
184157184Sache	  r = 0;
185157184Sache	}
186157184Sache      return r;
187157184Sache    }
188157184Sache
189157184Sache  return 1;
190119610Sache}
191119610Sache
192157184Sache/* Handle C-u style numeric args, as well as M--, and M-digits. */
193157184Sachestatic int
194157184Sacherl_digit_loop ()
195119610Sache{
196157184Sache  int c, r;
197119610Sache
198157184Sache  while (1)
199157184Sache    {
200157184Sache      if (_rl_arg_overflow ())
201157184Sache	return 1;
202157184Sache
203157184Sache      c = _rl_arg_getchar ();
204157184Sache
205157184Sache      if (c < 0)
206157184Sache	{
207157184Sache	  _rl_abort_internal ();
208157184Sache	  return -1;
209157184Sache	}
210157184Sache
211157184Sache      r = _rl_arg_dispatch (_rl_argcxt, c);
212157184Sache      if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
213157184Sache        break;
214157184Sache    }
215165670Sache
216165670Sache  return r;
217119610Sache}
218119610Sache
219119610Sache/* Create a default argument. */
220157184Sachevoid
221157184Sache_rl_reset_argument ()
222119610Sache{
223119610Sache  rl_numeric_arg = rl_arg_sign = 1;
224119610Sache  rl_explicit_arg = 0;
225157184Sache  _rl_argcxt = 0;
226119610Sache}
227119610Sache
228157184Sache/* Start a numeric argument with initial value KEY */
229157184Sacheint
230157184Sacherl_digit_argument (ignore, key)
231157184Sache     int ignore, key;
232157184Sache{
233157184Sache  _rl_arg_init ();
234157184Sache  if (RL_ISSTATE (RL_STATE_CALLBACK))
235157184Sache    {
236157184Sache      _rl_arg_dispatch (_rl_argcxt, key);
237157184Sache      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
238157184Sache      return 0;
239157184Sache    }
240157184Sache  else
241157184Sache    {
242157184Sache      rl_execute_next (key);
243157184Sache      return (rl_digit_loop ());
244157184Sache    }
245157184Sache}
246157184Sache
247119610Sache/* C-u, universal argument.  Multiply the current argument by 4.
248119610Sache   Read a key.  If the key has nothing to do with arguments, then
249119610Sache   dispatch on it.  If the key is the abort character then abort. */
250119610Sacheint
251119610Sacherl_universal_argument (count, key)
252119610Sache     int count, key;
253119610Sache{
254157184Sache  _rl_arg_init ();
255119610Sache  rl_numeric_arg *= 4;
256157184Sache
257157184Sache  return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
258119610Sache}
259119610Sache
260157184Sacheint
261157184Sache_rl_arg_callback (cxt)
262157184Sache     _rl_arg_cxt cxt;
263157184Sache{
264157184Sache  int c, r;
265157184Sache
266157184Sache  c = _rl_arg_getchar ();
267157184Sache
268157184Sache  if (_rl_argcxt & NUM_READONE)
269157184Sache    {
270157184Sache      _rl_argcxt &= ~NUM_READONE;
271157184Sache      rl_restore_prompt ();
272157184Sache      rl_clear_message ();
273157184Sache      RL_UNSETSTATE(RL_STATE_NUMERICARG);
274157184Sache      rl_execute_next (c);
275157184Sache      return 0;
276157184Sache    }
277157184Sache
278157184Sache  r = _rl_arg_dispatch (cxt, c);
279157184Sache  return (r != 1);
280157184Sache}
281157184Sache
282157184Sache/* What to do when you abort reading an argument. */
283157184Sacheint
284157184Sacherl_discard_argument ()
285157184Sache{
286157184Sache  rl_ding ();
287157184Sache  rl_clear_message ();
288157184Sache  _rl_reset_argument ();
289157184Sache
290157184Sache  return 0;
291157184Sache}
292157184Sache
293119610Sache/* **************************************************************** */
294119610Sache/*								    */
295119610Sache/*			History Utilities			    */
296119610Sache/*								    */
297119610Sache/* **************************************************************** */
298119610Sache
299119610Sache/* We already have a history library, and that is what we use to control
300119610Sache   the history features of readline.  This is our local interface to
301119610Sache   the history mechanism. */
302119610Sache
303119610Sache/* While we are editing the history, this is the saved
304119610Sache   version of the original line. */
305119610SacheHIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
306119610Sache
307119610Sache/* Set the history pointer back to the last entry in the history. */
308119610Sachevoid
309119610Sache_rl_start_using_history ()
310119610Sache{
311119610Sache  using_history ();
312119610Sache  if (_rl_saved_line_for_history)
313119610Sache    _rl_free_history_entry (_rl_saved_line_for_history);
314119610Sache
315119610Sache  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
316119610Sache}
317119610Sache
318119610Sache/* Free the contents (and containing structure) of a HIST_ENTRY. */
319119610Sachevoid
320119610Sache_rl_free_history_entry (entry)
321119610Sache     HIST_ENTRY *entry;
322119610Sache{
323119610Sache  if (entry == 0)
324119610Sache    return;
325157184Sache
326157184Sache  FREE (entry->line);
327157184Sache  FREE (entry->timestamp);
328157184Sache
329119610Sache  free (entry);
330119610Sache}
331119610Sache
332119610Sache/* Perhaps put back the current line if it has changed. */
333119610Sacheint
334119610Sacherl_maybe_replace_line ()
335119610Sache{
336119610Sache  HIST_ENTRY *temp;
337119610Sache
338119610Sache  temp = current_history ();
339119610Sache  /* If the current line has changed, save the changes. */
340119610Sache  if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
341119610Sache    {
342119610Sache      temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
343119610Sache      free (temp->line);
344157184Sache      FREE (temp->timestamp);
345119610Sache      free (temp);
346119610Sache    }
347119610Sache  return 0;
348119610Sache}
349119610Sache
350119610Sache/* Restore the _rl_saved_line_for_history if there is one. */
351119610Sacheint
352119610Sacherl_maybe_unsave_line ()
353119610Sache{
354119610Sache  if (_rl_saved_line_for_history)
355119610Sache    {
356136644Sache      /* Can't call with `1' because rl_undo_list might point to an undo
357136644Sache	 list from a history entry, as in rl_replace_from_history() below. */
358119610Sache      rl_replace_line (_rl_saved_line_for_history->line, 0);
359119610Sache      rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
360119610Sache      _rl_free_history_entry (_rl_saved_line_for_history);
361119610Sache      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
362119610Sache      rl_point = rl_end;	/* rl_replace_line sets rl_end */
363119610Sache    }
364119610Sache  else
365119610Sache    rl_ding ();
366119610Sache  return 0;
367119610Sache}
368119610Sache
369119610Sache/* Save the current line in _rl_saved_line_for_history. */
370119610Sacheint
371119610Sacherl_maybe_save_line ()
372119610Sache{
373119610Sache  if (_rl_saved_line_for_history == 0)
374119610Sache    {
375119610Sache      _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
376119610Sache      _rl_saved_line_for_history->line = savestring (rl_line_buffer);
377157184Sache      _rl_saved_line_for_history->timestamp = (char *)NULL;
378119610Sache      _rl_saved_line_for_history->data = (char *)rl_undo_list;
379119610Sache    }
380136644Sache
381119610Sache  return 0;
382119610Sache}
383119610Sache
384119610Sacheint
385119610Sache_rl_free_saved_history_line ()
386119610Sache{
387119610Sache  if (_rl_saved_line_for_history)
388119610Sache    {
389119610Sache      _rl_free_history_entry (_rl_saved_line_for_history);
390119610Sache      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
391119610Sache    }
392119610Sache  return 0;
393119610Sache}
394119610Sache
395119610Sachestatic void
396119610Sache_rl_history_set_point ()
397119610Sache{
398119610Sache  rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
399119610Sache		? _rl_history_saved_point
400119610Sache		: rl_end;
401119610Sache  if (rl_point > rl_end)
402119610Sache    rl_point = rl_end;
403119610Sache
404119610Sache#if defined (VI_MODE)
405136644Sache  if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
406119610Sache    rl_point = 0;
407119610Sache#endif /* VI_MODE */
408119610Sache
409119610Sache  if (rl_editing_mode == emacs_mode)
410119610Sache    rl_mark = (rl_point == rl_end ? 0 : rl_end);
411119610Sache}
412119610Sache
413119610Sachevoid
414119610Sacherl_replace_from_history (entry, flags)
415119610Sache     HIST_ENTRY *entry;
416119610Sache     int flags;			/* currently unused */
417119610Sache{
418136644Sache  /* Can't call with `1' because rl_undo_list might point to an undo list
419136644Sache     from a history entry, just like we're setting up here. */
420119610Sache  rl_replace_line (entry->line, 0);
421119610Sache  rl_undo_list = (UNDO_LIST *)entry->data;
422119610Sache  rl_point = rl_end;
423119610Sache  rl_mark = 0;
424119610Sache
425119610Sache#if defined (VI_MODE)
426119610Sache  if (rl_editing_mode == vi_mode)
427119610Sache    {
428119610Sache      rl_point = 0;
429119610Sache      rl_mark = rl_end;
430119610Sache    }
431119610Sache#endif
432119610Sache}
433119610Sache
434119610Sache/* **************************************************************** */
435119610Sache/*								    */
436119610Sache/*			History Commands			    */
437119610Sache/*								    */
438119610Sache/* **************************************************************** */
439119610Sache
440119610Sache/* Meta-< goes to the start of the history. */
441119610Sacheint
442119610Sacherl_beginning_of_history (count, key)
443119610Sache     int count, key;
444119610Sache{
445119610Sache  return (rl_get_previous_history (1 + where_history (), key));
446119610Sache}
447119610Sache
448119610Sache/* Meta-> goes to the end of the history.  (The current line). */
449119610Sacheint
450119610Sacherl_end_of_history (count, key)
451119610Sache     int count, key;
452119610Sache{
453119610Sache  rl_maybe_replace_line ();
454119610Sache  using_history ();
455119610Sache  rl_maybe_unsave_line ();
456119610Sache  return 0;
457119610Sache}
458119610Sache
459119610Sache/* Move down to the next history line. */
460119610Sacheint
461119610Sacherl_get_next_history (count, key)
462119610Sache     int count, key;
463119610Sache{
464119610Sache  HIST_ENTRY *temp;
465119610Sache
466119610Sache  if (count < 0)
467119610Sache    return (rl_get_previous_history (-count, key));
468119610Sache
469119610Sache  if (count == 0)
470119610Sache    return 0;
471119610Sache
472119610Sache  rl_maybe_replace_line ();
473119610Sache
474119610Sache  /* either not saved by rl_newline or at end of line, so set appropriately. */
475119610Sache  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
476119610Sache    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
477119610Sache
478119610Sache  temp = (HIST_ENTRY *)NULL;
479119610Sache  while (count)
480119610Sache    {
481119610Sache      temp = next_history ();
482119610Sache      if (!temp)
483119610Sache	break;
484119610Sache      --count;
485119610Sache    }
486119610Sache
487119610Sache  if (temp == 0)
488119610Sache    rl_maybe_unsave_line ();
489119610Sache  else
490119610Sache    {
491119610Sache      rl_replace_from_history (temp, 0);
492119610Sache      _rl_history_set_point ();
493119610Sache    }
494119610Sache  return 0;
495119610Sache}
496119610Sache
497119610Sache/* Get the previous item out of our interactive history, making it the current
498119610Sache   line.  If there is no previous history, just ding. */
499119610Sacheint
500119610Sacherl_get_previous_history (count, key)
501119610Sache     int count, key;
502119610Sache{
503119610Sache  HIST_ENTRY *old_temp, *temp;
504119610Sache
505119610Sache  if (count < 0)
506119610Sache    return (rl_get_next_history (-count, key));
507119610Sache
508119610Sache  if (count == 0)
509119610Sache    return 0;
510119610Sache
511119610Sache  /* either not saved by rl_newline or at end of line, so set appropriately. */
512119610Sache  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
513119610Sache    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
514119610Sache
515119610Sache  /* If we don't have a line saved, then save this one. */
516119610Sache  rl_maybe_save_line ();
517119610Sache
518119610Sache  /* If the current line has changed, save the changes. */
519119610Sache  rl_maybe_replace_line ();
520119610Sache
521119610Sache  temp = old_temp = (HIST_ENTRY *)NULL;
522119610Sache  while (count)
523119610Sache    {
524119610Sache      temp = previous_history ();
525119610Sache      if (temp == 0)
526119610Sache	break;
527119610Sache
528119610Sache      old_temp = temp;
529119610Sache      --count;
530119610Sache    }
531119610Sache
532119610Sache  /* If there was a large argument, and we moved back to the start of the
533119610Sache     history, that is not an error.  So use the last value found. */
534119610Sache  if (!temp && old_temp)
535119610Sache    temp = old_temp;
536119610Sache
537119610Sache  if (temp == 0)
538119610Sache    rl_ding ();
539119610Sache  else
540119610Sache    {
541119610Sache      rl_replace_from_history (temp, 0);
542119610Sache      _rl_history_set_point ();
543119610Sache    }
544136644Sache
545119610Sache  return 0;
546119610Sache}
547119610Sache
548119610Sache/* **************************************************************** */
549119610Sache/*								    */
550119610Sache/*			    Editing Modes			    */
551119610Sache/*								    */
552119610Sache/* **************************************************************** */
553119610Sache/* How to toggle back and forth between editing modes. */
554119610Sacheint
555119610Sacherl_vi_editing_mode (count, key)
556119610Sache     int count, key;
557119610Sache{
558119610Sache#if defined (VI_MODE)
559119610Sache  _rl_set_insert_mode (RL_IM_INSERT, 1);	/* vi mode ignores insert mode */
560119610Sache  rl_editing_mode = vi_mode;
561119610Sache  rl_vi_insertion_mode (1, key);
562119610Sache#endif /* VI_MODE */
563119610Sache
564119610Sache  return 0;
565119610Sache}
566119610Sache
567119610Sacheint
568119610Sacherl_emacs_editing_mode (count, key)
569119610Sache     int count, key;
570119610Sache{
571119610Sache  rl_editing_mode = emacs_mode;
572119610Sache  _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
573119610Sache  _rl_keymap = emacs_standard_keymap;
574119610Sache  return 0;
575119610Sache}
576119610Sache
577119610Sache/* Function for the rest of the library to use to set insert/overwrite mode. */
578119610Sachevoid
579119610Sache_rl_set_insert_mode (im, force)
580119610Sache     int im, force;
581119610Sache{
582119610Sache#ifdef CURSOR_MODE
583119610Sache  _rl_set_cursor (im, force);
584119610Sache#endif
585119610Sache
586119610Sache  rl_insert_mode = im;
587119610Sache}
588119610Sache
589119610Sache/* Toggle overwrite mode.  A positive explicit argument selects overwrite
590119610Sache   mode.  A negative or zero explicit argument selects insert mode. */
591119610Sacheint
592119610Sacherl_overwrite_mode (count, key)
593119610Sache     int count, key;
594119610Sache{
595119610Sache  if (rl_explicit_arg == 0)
596119610Sache    _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
597119610Sache  else if (count > 0)
598119610Sache    _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
599119610Sache  else
600119610Sache    _rl_set_insert_mode (RL_IM_INSERT, 0);
601119610Sache
602119610Sache  return 0;
603119610Sache}
604