* Sync comment with code's reality.
[dragonfly.git] / contrib / libreadline / readline.c
1 /* readline.c -- a general facility for reading lines of input
2    with emacs style editing and completion. */
3
4 /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
5
6    This file is part of the GNU Readline Library, a library for
7    reading lines of text with interactive input and history editing.
8
9    The GNU Readline Library is free software; you can redistribute it
10    and/or modify it under the terms of the GNU General Public License
11    as published by the Free Software Foundation; either version 2, or
12    (at your option) any later version.
13
14    The GNU Readline Library is distributed in the hope that it will be
15    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    The GNU General Public License is often shipped with GNU software, and
20    is generally kept in a file called COPYING or LICENSE.  If you do not
21    have a copy of the license, write to the Free Software Foundation,
22    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
24
25 #if defined (HAVE_CONFIG_H)
26 #  include <config.h>
27 #endif
28
29 #include <sys/types.h>
30 #include "posixstat.h"
31 #include <fcntl.h>
32 #if defined (HAVE_SYS_FILE_H)
33 #  include <sys/file.h>
34 #endif /* HAVE_SYS_FILE_H */
35
36 #if defined (HAVE_UNISTD_H)
37 #  include <unistd.h>
38 #endif /* HAVE_UNISTD_H */
39
40 #if defined (HAVE_STDLIB_H)
41 #  include <stdlib.h>
42 #else
43 #  include "ansi_stdlib.h"
44 #endif /* HAVE_STDLIB_H */
45
46 #if defined (HAVE_LOCALE_H)
47 #  include <locale.h>
48 #endif
49
50 #include <stdio.h>
51 #include "posixjmp.h"
52
53 /* System-specific feature definitions and include files. */
54 #include "rldefs.h"
55
56 #if defined (__EMX__)
57 #  define INCL_DOSPROCESS
58 #  include <os2.h>
59 #endif /* __EMX__ */
60
61 /* Some standard library routines. */
62 #include "readline.h"
63 #include "history.h"
64
65 #include "rlprivate.h"
66 #include "rlshell.h"
67 #include "xmalloc.h"
68
69 #ifndef RL_LIBRARY_VERSION
70 #  define RL_LIBRARY_VERSION "4.1"
71 #endif
72
73 /* Evaluates its arguments multiple times. */
74 #define SWAP(s, e)  do { int t; t = s; s = e; e = t; } while (0)
75
76 /* Forward declarations used in this file. */
77 void _rl_free_history_entry __P((HIST_ENTRY *));
78
79 static char *readline_internal __P((void));
80 static void readline_initialize_everything __P((void));
81 static void start_using_history __P((void));
82 static void bind_arrow_keys __P((void));
83 static int rl_change_case __P((int, int));
84
85 static void readline_default_bindings __P((void));
86
87 /* **************************************************************** */
88 /*                                                                  */
89 /*                      Line editing input utility                  */
90 /*                                                                  */
91 /* **************************************************************** */
92
93 char *rl_library_version = RL_LIBRARY_VERSION;
94
95 int rl_gnu_readline_p = 1;
96
97 /* A pointer to the keymap that is currently in use.
98    By default, it is the standard emacs keymap. */
99 Keymap _rl_keymap = emacs_standard_keymap;
100
101 /* The current style of editing. */
102 int rl_editing_mode = emacs_mode;
103
104 /* Non-zero if we called this function from _rl_dispatch().  It's present
105    so functions can find out whether they were called from a key binding
106    or directly from an application. */
107 int rl_dispatching;
108
109 /* Non-zero if the previous command was a kill command. */
110 int _rl_last_command_was_kill = 0;
111
112 /* The current value of the numeric argument specified by the user. */
113 int rl_numeric_arg = 1;
114
115 /* Non-zero if an argument was typed. */
116 int rl_explicit_arg = 0;
117
118 /* Temporary value used while generating the argument. */
119 int rl_arg_sign = 1;
120
121 /* Non-zero means we have been called at least once before. */
122 static int rl_initialized;
123
124 /* If non-zero, this program is running in an EMACS buffer. */
125 static int running_in_emacs;
126
127 /* The current offset in the current input line. */
128 int rl_point;
129
130 /* Mark in the current input line. */
131 int rl_mark;
132
133 /* Length of the current input line. */
134 int rl_end;
135
136 /* Make this non-zero to return the current input_line. */
137 int rl_done;
138
139 /* The last function executed by readline. */
140 Function *rl_last_func = (Function *)NULL;
141
142 /* Top level environment for readline_internal (). */
143 procenv_t readline_top_level;
144
145 /* The streams we interact with. */
146 FILE *_rl_in_stream, *_rl_out_stream;
147
148 /* The names of the streams that we do input and output to. */
149 FILE *rl_instream = (FILE *)NULL;
150 FILE *rl_outstream = (FILE *)NULL;
151
152 /* Non-zero means echo characters as they are read. */
153 int readline_echoing_p = 1;
154
155 /* Current prompt. */
156 char *rl_prompt;
157 int rl_visible_prompt_length = 0;
158
159 /* Set to non-zero by calling application if it has already printed rl_prompt
160    and does not want readline to do it the first time. */
161 int rl_already_prompted = 0;
162
163 /* The number of characters read in order to type this complete command. */
164 int rl_key_sequence_length = 0;
165
166 /* If non-zero, then this is the address of a function to call just
167    before readline_internal_setup () prints the first prompt. */
168 Function *rl_startup_hook = (Function *)NULL;
169
170 /* If non-zero, this is the address of a function to call just before
171    readline_internal_setup () returns and readline_internal starts
172    reading input characters. */
173 Function *rl_pre_input_hook = (Function *)NULL;
174
175 /* What we use internally.  You should always refer to RL_LINE_BUFFER. */
176 static char *the_line;
177
178 /* The character that can generate an EOF.  Really read from
179    the terminal driver... just defaulted here. */
180 int _rl_eof_char = CTRL ('D');
181
182 /* Non-zero makes this the next keystroke to read. */
183 int rl_pending_input = 0;
184
185 /* Pointer to a useful terminal name. */
186 char *rl_terminal_name = (char *)NULL;
187
188 /* Non-zero means to always use horizontal scrolling in line display. */
189 int _rl_horizontal_scroll_mode = 0;
190
191 /* Non-zero means to display an asterisk at the starts of history lines
192    which have been modified. */
193 int _rl_mark_modified_lines = 0;  
194
195 /* The style of `bell' notification preferred.  This can be set to NO_BELL,
196    AUDIBLE_BELL, or VISIBLE_BELL. */
197 int _rl_bell_preference = AUDIBLE_BELL;
198      
199 /* String inserted into the line by rl_insert_comment (). */
200 char *_rl_comment_begin;
201
202 /* Keymap holding the function currently being executed. */
203 Keymap rl_executing_keymap;
204
205 /* Non-zero means to erase entire line, including prompt, on empty input lines. */
206 int rl_erase_empty_line = 0;
207
208 /* Non-zero means to read only this many characters rather than up to a
209    character bound to accept-line. */
210 int rl_num_chars_to_read;
211
212 /* Line buffer and maintenence. */
213 char *rl_line_buffer = (char *)NULL;
214 int rl_line_buffer_len = 0;
215
216 /* Forward declarations used by the display and termcap code. */
217
218 /* **************************************************************** */
219 /*                                                                  */
220 /*                      `Forward' declarations                      */
221 /*                                                                  */
222 /* **************************************************************** */
223
224 /* Non-zero means do not parse any lines other than comments and
225    parser directives. */
226 unsigned char _rl_parsing_conditionalized_out = 0;
227
228 /* Non-zero means to convert characters with the meta bit set to
229    escape-prefixed characters so we can indirect through
230    emacs_meta_keymap or vi_escape_keymap. */
231 int _rl_convert_meta_chars_to_ascii = 1;
232
233 /* Non-zero means to output characters with the meta bit set directly
234    rather than as a meta-prefixed escape sequence. */
235 int _rl_output_meta_chars = 0;
236
237 /* **************************************************************** */
238 /*                                                                  */
239 /*                      Top Level Functions                         */
240 /*                                                                  */
241 /* **************************************************************** */
242
243 /* Non-zero means treat 0200 bit in terminal input as Meta bit. */
244 int _rl_meta_flag = 0;  /* Forward declaration */
245
246 /* Read a line of input.  Prompt with PROMPT.  An empty PROMPT means
247    none.  A return value of NULL means that EOF was encountered. */
248 char *
249 readline (prompt)
250      char *prompt;
251 {
252   char *value;
253
254   rl_prompt = prompt;
255
256   /* If we are at EOF return a NULL string. */
257   if (rl_pending_input == EOF)
258     {
259       rl_pending_input = 0;
260       return ((char *)NULL);
261     }
262
263   rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
264
265   rl_initialize ();
266   (*rl_prep_term_function) (_rl_meta_flag);
267
268 #if defined (HANDLE_SIGNALS)
269   rl_set_signals ();
270 #endif
271
272   value = readline_internal ();
273   (*rl_deprep_term_function) ();
274
275 #if defined (HANDLE_SIGNALS)
276   rl_clear_signals ();
277 #endif
278
279   return (value);
280 }
281
282 #if defined (READLINE_CALLBACKS)
283 #  define STATIC_CALLBACK
284 #else
285 #  define STATIC_CALLBACK static
286 #endif
287
288 STATIC_CALLBACK void
289 readline_internal_setup ()
290 {
291   char *nprompt;
292
293   _rl_in_stream = rl_instream;
294   _rl_out_stream = rl_outstream;
295
296   if (rl_startup_hook)
297     (*rl_startup_hook) ();
298
299   if (readline_echoing_p == 0)
300     {
301       if (rl_prompt && rl_already_prompted == 0)
302         {
303           nprompt = _rl_strip_prompt (rl_prompt);
304           fprintf (_rl_out_stream, "%s", nprompt);
305           fflush (_rl_out_stream);
306           free (nprompt);
307         }
308     }
309   else
310     {
311       if (rl_prompt && rl_already_prompted)
312         rl_on_new_line_with_prompt ();
313       else
314         rl_on_new_line ();
315       (*rl_redisplay_function) ();
316 #if defined (VI_MODE)
317       if (rl_editing_mode == vi_mode)
318         rl_vi_insertion_mode (1, 0);
319 #endif /* VI_MODE */
320     }
321
322   if (rl_pre_input_hook)
323     (*rl_pre_input_hook) ();
324 }
325
326 STATIC_CALLBACK char *
327 readline_internal_teardown (eof)
328      int eof;
329 {
330   char *temp;
331   HIST_ENTRY *entry;
332
333   /* Restore the original of this history line, iff the line that we
334      are editing was originally in the history, AND the line has changed. */
335   entry = current_history ();
336
337   if (entry && rl_undo_list)
338     {
339       temp = savestring (the_line);
340       rl_revert_line (1, 0);
341       entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL);
342       _rl_free_history_entry (entry);
343
344       strcpy (the_line, temp);
345       free (temp);
346     }
347
348   /* At any rate, it is highly likely that this line has an undo list.  Get
349      rid of it now. */
350   if (rl_undo_list)
351     free_undo_list ();
352
353   return (eof ? (char *)NULL : savestring (the_line));
354 }
355
356 STATIC_CALLBACK int
357 #if defined (READLINE_CALLBACKS)
358 readline_internal_char ()
359 #else
360 readline_internal_charloop ()
361 #endif
362 {
363   static int lastc, eof_found;
364   int c, code, lk;
365
366   lastc = -1;
367   eof_found = 0;
368
369 #if !defined (READLINE_CALLBACKS)
370   while (rl_done == 0)
371     {
372 #endif
373       lk = _rl_last_command_was_kill;
374
375       code = setjmp (readline_top_level);
376
377       if (code)
378         (*rl_redisplay_function) ();
379
380       if (rl_pending_input == 0)
381         {
382           /* Then initialize the argument and number of keys read. */
383           _rl_init_argument ();
384           rl_key_sequence_length = 0;
385         }
386
387       c = rl_read_key ();
388
389       /* EOF typed to a non-blank line is a <NL>. */
390       if (c == EOF && rl_end)
391         c = NEWLINE;
392
393       /* The character _rl_eof_char typed to blank line, and not as the
394          previous character is interpreted as EOF. */
395       if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
396         {
397 #if defined (READLINE_CALLBACKS)
398           return (rl_done = 1);
399 #else
400           eof_found = 1;
401           break;
402 #endif
403         }
404
405       lastc = c;
406       _rl_dispatch ((unsigned char)c, _rl_keymap);
407
408       /* If there was no change in _rl_last_command_was_kill, then no kill
409          has taken place.  Note that if input is pending we are reading
410          a prefix command, so nothing has changed yet. */
411       if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
412         _rl_last_command_was_kill = 0;
413
414 #if defined (VI_MODE)
415       /* In vi mode, when you exit insert mode, the cursor moves back
416          over the previous character.  We explicitly check for that here. */
417       if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
418         rl_vi_check ();
419 #endif /* VI_MODE */
420
421       if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
422         {
423           (*rl_redisplay_function) ();
424           rl_newline (1, '\n');
425         }
426
427       if (rl_done == 0)
428         (*rl_redisplay_function) ();
429
430       /* If the application writer has told us to erase the entire line if
431           the only character typed was something bound to rl_newline, do so. */
432       if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
433           rl_point == 0 && rl_end == 0)
434         _rl_erase_entire_line ();
435
436 #if defined (READLINE_CALLBACKS)
437       return 0;
438 #else
439     }
440
441   return (eof_found);
442 #endif
443 }
444
445 #if defined (READLINE_CALLBACKS)
446 static int
447 readline_internal_charloop ()
448 {
449   int eof = 1;
450
451   while (rl_done == 0)
452     eof = readline_internal_char ();
453   return (eof);
454 }
455 #endif /* READLINE_CALLBACKS */
456
457 /* Read a line of input from the global rl_instream, doing output on
458    the global rl_outstream.
459    If rl_prompt is non-null, then that is our prompt. */
460 static char *
461 readline_internal ()
462 {
463   int eof;
464
465   readline_internal_setup ();
466   eof = readline_internal_charloop ();
467   return (readline_internal_teardown (eof));
468 }
469
470 void
471 _rl_init_line_state ()
472 {
473   rl_point = rl_end = 0;
474   the_line = rl_line_buffer;
475   the_line[0] = 0;
476 }
477
478 void
479 _rl_set_the_line ()
480 {
481   the_line = rl_line_buffer;
482 }
483
484 /* Do the command associated with KEY in MAP.
485    If the associated command is really a keymap, then read
486    another key, and dispatch into that map. */
487 int
488 _rl_dispatch (key, map)
489      register int key;
490      Keymap map;
491 {
492   int r, newkey;
493   char *macro;
494   Function *func;
495
496   if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
497     {
498       if (map[ESC].type == ISKMAP)
499         {
500           if (_rl_defining_kbd_macro)
501             _rl_add_macro_char (ESC);
502           map = FUNCTION_TO_KEYMAP (map, ESC);
503           key = UNMETA (key);
504           rl_key_sequence_length += 2;
505           return (_rl_dispatch (key, map));
506         }
507       else
508         ding ();
509       return 0;
510     }
511
512   if (_rl_defining_kbd_macro)
513     _rl_add_macro_char (key);
514
515   r = 0;
516   switch (map[key].type)
517     {
518     case ISFUNC:
519       func = map[key].function;
520       if (func != (Function *)NULL)
521         {
522           /* Special case rl_do_lowercase_version (). */
523           if (func == rl_do_lowercase_version)
524             return (_rl_dispatch (_rl_to_lower (key), map));
525
526           rl_executing_keymap = map;
527
528 #if 0
529           _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
530 #endif
531
532           rl_dispatching = 1;
533           r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
534           rl_dispatching = 0;
535
536           /* If we have input pending, then the last command was a prefix
537              command.  Don't change the state of rl_last_func.  Otherwise,
538              remember the last command executed in this variable. */
539           if (!rl_pending_input && map[key].function != rl_digit_argument)
540             rl_last_func = map[key].function;
541         }
542       else
543         {
544           _rl_abort_internal ();
545           return -1;
546         }
547       break;
548
549     case ISKMAP:
550       if (map[key].function != (Function *)NULL)
551         {
552           rl_key_sequence_length++;
553           newkey = rl_read_key ();
554           r = _rl_dispatch (newkey, FUNCTION_TO_KEYMAP (map, key));
555         }
556       else
557         {
558           _rl_abort_internal ();
559           return -1;
560         }
561       break;
562
563     case ISMACR:
564       if (map[key].function != (Function *)NULL)
565         {
566           macro = savestring ((char *)map[key].function);
567           _rl_with_macro_input (macro);
568           return 0;
569         }
570       break;
571     }
572 #if defined (VI_MODE)
573   if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
574       _rl_vi_textmod_command (key))
575     _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
576 #endif
577   return (r);
578 }
579
580 /* **************************************************************** */
581 /*                                                                  */
582 /*                      Initializations                             */
583 /*                                                                  */
584 /* **************************************************************** */
585
586 /* Initialize readline (and terminal if not already). */
587 int
588 rl_initialize ()
589 {
590   /* If we have never been called before, initialize the
591      terminal and data structures. */
592   if (!rl_initialized)
593     {
594       readline_initialize_everything ();
595       rl_initialized++;
596     }
597
598   /* Initalize the current line information. */
599   _rl_init_line_state ();
600
601   /* We aren't done yet.  We haven't even gotten started yet! */
602   rl_done = 0;
603
604   /* Tell the history routines what is going on. */
605   start_using_history ();
606
607   /* Make the display buffer match the state of the line. */
608   rl_reset_line_state ();
609
610   /* No such function typed yet. */
611   rl_last_func = (Function *)NULL;
612
613   /* Parsing of key-bindings begins in an enabled state. */
614   _rl_parsing_conditionalized_out = 0;
615
616 #if defined (VI_MODE)
617   if (rl_editing_mode == vi_mode)
618     _rl_vi_initialize_line ();
619 #endif
620
621   return 0;
622 }
623
624 #if 0
625 #if defined (__EMX__)
626 static void
627 _emx_build_environ ()
628 {
629   TIB *tibp;
630   PIB *pibp;
631   char *t, **tp;
632   int c;
633
634   DosGetInfoBlocks (&tibp, &pibp);
635   t = pibp->pib_pchenv;
636   for (c = 1; *t; c++)
637     t += strlen (t) + 1;
638   tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *));
639   t = pibp->pib_pchenv;
640   while (*t)
641     {
642       *tp++ = t;
643       t += strlen (t) + 1;
644     }
645   *tp = 0;
646 }
647 #endif /* __EMX__ */
648 #endif
649
650 /* Initialize the entire state of the world. */
651 static void
652 readline_initialize_everything ()
653 {
654 #if 0
655 #if defined (__EMX__)
656   if (environ == 0)
657     _emx_build_environ ();
658 #endif
659 #endif
660
661   /* Find out if we are running in Emacs. */
662   running_in_emacs = get_env_value ("EMACS") != (char *)0;
663
664   /* Set up input and output if they are not already set up. */
665   if (!rl_instream)
666     rl_instream = stdin;
667
668   if (!rl_outstream)
669     rl_outstream = stdout;
670
671   /* Bind _rl_in_stream and _rl_out_stream immediately.  These values
672      may change, but they may also be used before readline_internal ()
673      is called. */
674   _rl_in_stream = rl_instream;
675   _rl_out_stream = rl_outstream;
676
677   /* Allocate data structures. */
678   if (rl_line_buffer == 0)
679     rl_line_buffer = xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
680
681   /* Initialize the terminal interface. */
682   _rl_init_terminal_io ((char *)NULL);
683
684   /* Bind tty characters to readline functions. */
685   readline_default_bindings ();
686
687   /* Initialize the function names. */
688   rl_initialize_funmap ();
689
690   /* Decide whether we should automatically go into eight-bit mode. */
691   _rl_init_eightbit ();
692       
693   /* Read in the init file. */
694   rl_read_init_file ((char *)NULL);
695
696   /* XXX */
697   if (_rl_horizontal_scroll_mode && _rl_term_autowrap)
698     {
699       screenwidth--;
700       screenchars -= screenheight;
701     }
702
703   /* Override the effect of any `set keymap' assignments in the
704      inputrc file. */
705   rl_set_keymap_from_edit_mode ();
706
707   /* Try to bind a common arrow key prefix, if not already bound. */
708   bind_arrow_keys ();
709
710   /* Enable the meta key, if this terminal has one. */
711   if (_rl_enable_meta)
712     _rl_enable_meta_key ();
713
714   /* If the completion parser's default word break characters haven't
715      been set yet, then do so now. */
716   if (rl_completer_word_break_characters == (char *)NULL)
717     rl_completer_word_break_characters = rl_basic_word_break_characters;
718 }
719
720 /* If this system allows us to look at the values of the regular
721    input editing characters, then bind them to their readline
722    equivalents, iff the characters are not bound to keymaps. */
723 static void
724 readline_default_bindings ()
725 {
726   rltty_set_default_bindings (_rl_keymap);
727 }
728
729 static void
730 bind_arrow_keys_internal ()
731 {
732   Function *f;
733
734 #if defined (__MSDOS__)
735   f = rl_function_of_keyseq ("\033[0A", _rl_keymap, (int *)NULL);
736   if (!f || f == rl_do_lowercase_version)
737     {
738        _rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
739        _rl_bind_if_unbound ("\033[0B", rl_backward);
740        _rl_bind_if_unbound ("\033[0C", rl_forward);
741        _rl_bind_if_unbound ("\033[0D", rl_get_next_history);
742     }
743 #endif
744         
745   f = rl_function_of_keyseq ("\033[A", _rl_keymap, (int *)NULL);
746   if (!f || f == rl_do_lowercase_version)
747     {
748       _rl_bind_if_unbound ("\033[A", rl_get_previous_history);
749       _rl_bind_if_unbound ("\033[B", rl_get_next_history);
750       _rl_bind_if_unbound ("\033[C", rl_forward);
751       _rl_bind_if_unbound ("\033[D", rl_backward);
752     }
753
754   f = rl_function_of_keyseq ("\033OA", _rl_keymap, (int *)NULL);
755   if (!f || f == rl_do_lowercase_version)
756     {
757       _rl_bind_if_unbound ("\033OA", rl_get_previous_history);
758       _rl_bind_if_unbound ("\033OB", rl_get_next_history);
759       _rl_bind_if_unbound ("\033OC", rl_forward);
760       _rl_bind_if_unbound ("\033OD", rl_backward);
761     }
762 }
763
764 /* Try and bind the common arrow key prefix after giving termcap and
765    the inputrc file a chance to bind them and create `real' keymaps
766    for the arrow key prefix. */
767 static void
768 bind_arrow_keys ()
769 {
770   Keymap xkeymap;
771
772   xkeymap = _rl_keymap;
773
774   _rl_keymap = emacs_standard_keymap;
775   bind_arrow_keys_internal ();
776
777 #if defined (VI_MODE)
778   _rl_keymap = vi_movement_keymap;
779   bind_arrow_keys_internal ();
780 #endif
781
782   _rl_keymap = xkeymap;
783 }
784
785 \f
786 /* **************************************************************** */
787 /*                                                                  */
788 /*                      Numeric Arguments                           */
789 /*                                                                  */
790 /* **************************************************************** */
791
792 /* Handle C-u style numeric args, as well as M--, and M-digits. */
793 static int
794 rl_digit_loop ()
795 {
796   int key, c, sawminus, sawdigits;
797
798   rl_save_prompt ();
799
800   sawminus = sawdigits = 0;
801   while (1)
802     {
803       if (rl_numeric_arg > 1000000)
804         {
805           sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
806           ding ();
807           rl_restore_prompt ();
808           rl_clear_message ();
809           return 1;
810         }
811       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
812       key = c = rl_read_key ();
813
814       /* If we see a key bound to `universal-argument' after seeing digits,
815          it ends the argument but is otherwise ignored. */
816       if (_rl_keymap[c].type == ISFUNC &&
817           _rl_keymap[c].function == rl_universal_argument)
818         {
819           if (sawdigits == 0)
820             {
821               rl_numeric_arg *= 4;
822               continue;
823             }
824           else
825             {
826               key = rl_read_key ();
827               rl_restore_prompt ();
828               rl_clear_message ();
829               return (_rl_dispatch (key, _rl_keymap));
830             }
831         }
832
833       c = UNMETA (c);
834
835       if (_rl_digit_p (c))
836         {
837           rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
838           sawdigits = rl_explicit_arg = 1;
839         }
840       else if (c == '-' && rl_explicit_arg == 0)
841         {
842           rl_numeric_arg = sawminus = 1;
843           rl_arg_sign = -1;
844         }
845       else
846         {
847           /* Make M-- command equivalent to M--1 command. */
848           if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
849             rl_explicit_arg = 1;
850           rl_restore_prompt ();
851           rl_clear_message ();
852           return (_rl_dispatch (key, _rl_keymap));
853         }
854     }
855
856   return 0;
857 }
858
859 /* Add the current digit to the argument in progress. */
860 int
861 rl_digit_argument (ignore, key)
862      int ignore, key;
863 {
864   rl_pending_input = key;
865   return (rl_digit_loop ());
866 }
867
868 /* What to do when you abort reading an argument. */
869 int
870 rl_discard_argument ()
871 {
872   ding ();
873   rl_clear_message ();
874   _rl_init_argument ();
875   return 0;
876 }
877
878 /* Create a default argument. */
879 int
880 _rl_init_argument ()
881 {
882   rl_numeric_arg = rl_arg_sign = 1;
883   rl_explicit_arg = 0;
884   return 0;
885 }
886
887 /* C-u, universal argument.  Multiply the current argument by 4.
888    Read a key.  If the key has nothing to do with arguments, then
889    dispatch on it.  If the key is the abort character then abort. */
890 int
891 rl_universal_argument (count, key)
892      int count, key;
893 {
894   rl_numeric_arg *= 4;
895   return (rl_digit_loop ());
896 }
897
898 /* **************************************************************** */
899 /*                                                                  */
900 /*                      Insert and Delete                           */
901 /*                                                                  */
902 /* **************************************************************** */
903
904 /* Insert a string of text into the line at point.  This is the only
905    way that you should do insertion.  rl_insert () calls this
906    function. */
907 int
908 rl_insert_text (string)
909      char *string;
910 {
911   register int i, l = strlen (string);
912
913   if (rl_end + l >= rl_line_buffer_len)
914     rl_extend_line_buffer (rl_end + l);
915
916   for (i = rl_end; i >= rl_point; i--)
917     the_line[i + l] = the_line[i];
918   strncpy (the_line + rl_point, string, l);
919
920   /* Remember how to undo this if we aren't undoing something. */
921   if (!_rl_doing_an_undo)
922     {
923       /* If possible and desirable, concatenate the undos. */
924       if ((l == 1) &&
925           rl_undo_list &&
926           (rl_undo_list->what == UNDO_INSERT) &&
927           (rl_undo_list->end == rl_point) &&
928           (rl_undo_list->end - rl_undo_list->start < 20))
929         rl_undo_list->end++;
930       else
931         rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
932     }
933   rl_point += l;
934   rl_end += l;
935   the_line[rl_end] = '\0';
936   return l;
937 }
938
939 /* Delete the string between FROM and TO.  FROM is
940    inclusive, TO is not. */
941 int
942 rl_delete_text (from, to)
943      int from, to;
944 {
945   register char *text;
946   register int diff, i;
947
948   /* Fix it if the caller is confused. */
949   if (from > to)
950     SWAP (from, to);
951
952   /* fix boundaries */
953   if (to > rl_end)
954     {
955       to = rl_end;
956       if (from > to)
957         from = to;
958     }
959
960   text = rl_copy_text (from, to);
961
962   /* Some versions of strncpy() can't handle overlapping arguments. */
963   diff = to - from;
964   for (i = from; i < rl_end - diff; i++)
965     the_line[i] = the_line[i + diff];
966
967   /* Remember how to undo this delete. */
968   if (_rl_doing_an_undo == 0)
969     rl_add_undo (UNDO_DELETE, from, to, text);
970   else
971     free (text);
972
973   rl_end -= diff;
974   the_line[rl_end] = '\0';
975   return (diff);
976 }
977
978 /* Fix up point so that it is within the line boundaries after killing
979    text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
980    boundaries also. */
981
982 #define _RL_FIX_POINT(x) \
983         do { \
984         if (x > rl_end) \
985           x = rl_end; \
986         else if (x < 0) \
987           x = 0; \
988         } while (0)
989
990 void
991 _rl_fix_point (fix_mark_too)
992      int fix_mark_too;
993 {
994   _RL_FIX_POINT (rl_point);
995   if (fix_mark_too)
996     _RL_FIX_POINT (rl_mark);
997 }
998 #undef _RL_FIX_POINT
999
1000 void
1001 _rl_replace_text (text, start, end)
1002      char *text;
1003      int start, end;
1004 {
1005   rl_begin_undo_group ();
1006   rl_delete_text (start, end + 1);
1007   rl_point = start;
1008   rl_insert_text (text);
1009   rl_end_undo_group ();
1010 }
1011
1012 /* **************************************************************** */
1013 /*                                                                  */
1014 /*                      Readline character functions                */
1015 /*                                                                  */
1016 /* **************************************************************** */
1017
1018 /* This is not a gap editor, just a stupid line input routine.  No hair
1019    is involved in writing any of the functions, and none should be. */
1020
1021 /* Note that:
1022
1023    rl_end is the place in the string that we would place '\0';
1024    i.e., it is always safe to place '\0' there.
1025
1026    rl_point is the place in the string where the cursor is.  Sometimes
1027    this is the same as rl_end.
1028
1029    Any command that is called interactively receives two arguments.
1030    The first is a count: the numeric arg pased to this command.
1031    The second is the key which invoked this command.
1032 */
1033
1034 /* **************************************************************** */
1035 /*                                                                  */
1036 /*                      Movement Commands                           */
1037 /*                                                                  */
1038 /* **************************************************************** */
1039
1040 /* Note that if you `optimize' the display for these functions, you cannot
1041    use said functions in other functions which do not do optimizing display.
1042    I.e., you will have to update the data base for rl_redisplay, and you
1043    might as well let rl_redisplay do that job. */
1044
1045 /* Move forward COUNT characters. */
1046 int
1047 rl_forward (count, key)
1048      int count, key;
1049 {
1050   if (count < 0)
1051     rl_backward (-count, key);
1052   else if (count > 0)
1053     {
1054       int end = rl_point + count;
1055 #if defined (VI_MODE)
1056       int lend = rl_end - (rl_editing_mode == vi_mode);
1057 #else
1058       int lend = rl_end;
1059 #endif
1060
1061       if (end > lend)
1062         {
1063           rl_point = lend;
1064           ding ();
1065         }
1066       else
1067         rl_point = end;
1068     }
1069
1070   if (rl_end < 0)
1071     rl_end = 0;
1072
1073   return 0;
1074 }
1075
1076 /* Move backward COUNT characters. */
1077 int
1078 rl_backward (count, key)
1079      int count, key;
1080 {
1081   if (count < 0)
1082     rl_forward (-count, key);
1083   else if (count > 0)
1084     {
1085       if (rl_point < count)
1086         {
1087           rl_point = 0;
1088           ding ();
1089         }
1090       else
1091         rl_point -= count;
1092     }
1093   return 0;
1094 }
1095
1096 /* Move to the beginning of the line. */
1097 int
1098 rl_beg_of_line (count, key)
1099      int count, key;
1100 {
1101   rl_point = 0;
1102   return 0;
1103 }
1104
1105 /* Move to the end of the line. */
1106 int
1107 rl_end_of_line (count, key)
1108      int count, key;
1109 {
1110   rl_point = rl_end;
1111   return 0;
1112 }
1113
1114 /* Move forward a word.  We do what Emacs does. */
1115 int
1116 rl_forward_word (count, key)
1117      int count, key;
1118 {
1119   int c;
1120
1121   if (count < 0)
1122     {
1123       rl_backward_word (-count, key);
1124       return 0;
1125     }
1126
1127   while (count)
1128     {
1129       if (rl_point == rl_end)
1130         return 0;
1131
1132       /* If we are not in a word, move forward until we are in one.
1133          Then, move forward until we hit a non-alphabetic character. */
1134       c = the_line[rl_point];
1135       if (alphabetic (c) == 0)
1136         {
1137           while (++rl_point < rl_end)
1138             {
1139               c = the_line[rl_point];
1140               if (alphabetic (c))
1141                 break;
1142             }
1143         }
1144       if (rl_point == rl_end)
1145         return 0;
1146       while (++rl_point < rl_end)
1147         {
1148           c = the_line[rl_point];
1149           if (alphabetic (c) == 0)
1150             break;
1151         }
1152       --count;
1153     }
1154   return 0;
1155 }
1156
1157 /* Move backward a word.  We do what Emacs does. */
1158 int
1159 rl_backward_word (count, key)
1160      int count, key;
1161 {
1162   int c;
1163
1164   if (count < 0)
1165     {
1166       rl_forward_word (-count, key);
1167       return 0;
1168     }
1169
1170   while (count)
1171     {
1172       if (!rl_point)
1173         return 0;
1174
1175       /* Like rl_forward_word (), except that we look at the characters
1176          just before point. */
1177
1178       c = the_line[rl_point - 1];
1179       if (alphabetic (c) == 0)
1180         {
1181           while (--rl_point)
1182             {
1183               c = the_line[rl_point - 1];
1184               if (alphabetic (c))
1185                 break;
1186             }
1187         }
1188
1189       while (rl_point)
1190         {
1191           c = the_line[rl_point - 1];
1192           if (alphabetic (c) == 0)
1193             break;
1194           else
1195             --rl_point;
1196         }
1197       --count;
1198     }
1199   return 0;
1200 }
1201
1202 /* Clear the current line.  Numeric argument to C-l does this. */
1203 int
1204 rl_refresh_line (ignore1, ignore2)
1205      int ignore1, ignore2;
1206 {
1207   int curr_line;
1208
1209   curr_line = _rl_current_display_line ();
1210
1211   _rl_move_vert (curr_line);
1212   _rl_move_cursor_relative (0, the_line);   /* XXX is this right */
1213
1214   _rl_clear_to_eol (0);         /* arg of 0 means to not use spaces */
1215
1216   rl_forced_update_display ();
1217   rl_display_fixed = 1;
1218
1219   return 0;
1220 }
1221
1222 /* C-l typed to a line without quoting clears the screen, and then reprints
1223    the prompt and the current input line.  Given a numeric arg, redraw only
1224    the current line. */
1225 int
1226 rl_clear_screen (count, key)
1227      int count, key;
1228 {
1229   if (rl_explicit_arg)
1230     {
1231       rl_refresh_line (count, key);
1232       return 0;
1233     }
1234
1235   _rl_clear_screen ();          /* calls termcap function to clear screen */
1236   rl_forced_update_display ();
1237   rl_display_fixed = 1;
1238
1239   return 0;
1240 }
1241
1242 int
1243 rl_arrow_keys (count, c)
1244      int count, c;
1245 {
1246   int ch;
1247
1248   ch = rl_read_key ();
1249
1250   switch (_rl_to_upper (ch))
1251     {
1252     case 'A':
1253       rl_get_previous_history (count, ch);
1254       break;
1255
1256     case 'B':
1257       rl_get_next_history (count, ch);
1258       break;
1259
1260     case 'C':
1261       rl_forward (count, ch);
1262       break;
1263
1264     case 'D':
1265       rl_backward (count, ch);
1266       break;
1267
1268     default:
1269       ding ();
1270     }
1271   return 0;
1272 }
1273
1274 \f
1275 /* **************************************************************** */
1276 /*                                                                  */
1277 /*                      Text commands                               */
1278 /*                                                                  */
1279 /* **************************************************************** */
1280
1281 /* Insert the character C at the current location, moving point forward. */
1282 int
1283 rl_insert (count, c)
1284      int count, c;
1285 {
1286   register int i;
1287   char *string;
1288
1289   if (count <= 0)
1290     return 0;
1291
1292   /* If we can optimize, then do it.  But don't let people crash
1293      readline because of extra large arguments. */
1294   if (count > 1 && count <= 1024)
1295     {
1296       string = xmalloc (1 + count);
1297
1298       for (i = 0; i < count; i++)
1299         string[i] = c;
1300
1301       string[i] = '\0';
1302       rl_insert_text (string);
1303       free (string);
1304
1305       return 0;
1306     }
1307
1308   if (count > 1024)
1309     {
1310       int decreaser;
1311       char str[1024+1];
1312
1313       for (i = 0; i < 1024; i++)
1314         str[i] = c;
1315
1316       while (count)
1317         {
1318           decreaser = (count > 1024 ? 1024 : count);
1319           str[decreaser] = '\0';
1320           rl_insert_text (str);
1321           count -= decreaser;
1322         }
1323
1324       return 0;
1325     }
1326
1327   /* We are inserting a single character.
1328      If there is pending input, then make a string of all of the
1329      pending characters that are bound to rl_insert, and insert
1330      them all. */
1331   if (_rl_any_typein ())
1332     _rl_insert_typein (c);
1333   else
1334     {
1335       /* Inserting a single character. */
1336       char str[2];
1337
1338       str[1] = '\0';
1339       str[0] = c;
1340       rl_insert_text (str);
1341     }
1342   return 0;
1343 }
1344
1345 /* Insert the next typed character verbatim. */
1346 int
1347 rl_quoted_insert (count, key)
1348      int count, key;
1349 {
1350   int c;
1351
1352 #if defined (HANDLE_SIGNALS)
1353   _rl_disable_tty_signals ();
1354 #endif
1355   c = rl_read_key ();
1356 #if defined (HANDLE_SIGNALS)
1357   _rl_restore_tty_signals ();
1358 #endif
1359
1360   return (rl_insert (count, c));  
1361 }
1362
1363 /* Insert a tab character. */
1364 int
1365 rl_tab_insert (count, key)
1366      int count, key;
1367 {
1368   return (rl_insert (count, '\t'));
1369 }
1370
1371 /* What to do when a NEWLINE is pressed.  We accept the whole line.
1372    KEY is the key that invoked this command.  I guess it could have
1373    meaning in the future. */
1374 int
1375 rl_newline (count, key)
1376      int count, key;
1377 {
1378   rl_done = 1;
1379
1380 #if defined (VI_MODE)
1381   if (rl_editing_mode == vi_mode)
1382     {
1383       _rl_vi_done_inserting ();
1384       _rl_vi_reset_last ();
1385     }
1386 #endif /* VI_MODE */
1387
1388   /* If we've been asked to erase empty lines, suppress the final update,
1389      since _rl_update_final calls crlf(). */
1390   if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
1391     return 0;
1392
1393   if (readline_echoing_p)
1394     _rl_update_final ();
1395   return 0;
1396 }
1397
1398 /* What to do for some uppercase characters, like meta characters,
1399    and some characters appearing in emacs_ctlx_keymap.  This function
1400    is just a stub, you bind keys to it and the code in _rl_dispatch ()
1401    is special cased. */
1402 int
1403 rl_do_lowercase_version (ignore1, ignore2)
1404      int ignore1, ignore2;
1405 {
1406   return 0;
1407 }
1408
1409 /* Rubout the character behind point. */
1410 int
1411 rl_rubout (count, key)
1412      int count, key;
1413 {
1414   if (count < 0)
1415     {
1416       rl_delete (-count, key);
1417       return 0;
1418     }
1419
1420   if (!rl_point)
1421     {
1422       ding ();
1423       return -1;
1424     }
1425
1426   if (count > 1 || rl_explicit_arg)
1427     {
1428       int orig_point = rl_point;
1429       rl_backward (count, key);
1430       rl_kill_text (orig_point, rl_point);
1431     }
1432   else
1433     {
1434       int c = the_line[--rl_point];
1435       rl_delete_text (rl_point, rl_point + 1);
1436
1437       if (rl_point == rl_end && isprint (c) && _rl_last_c_pos)
1438         {
1439           int l;
1440           l = rl_character_len (c, rl_point);
1441           _rl_erase_at_end_of_line (l);
1442         }
1443     }
1444   return 0;
1445 }
1446
1447 /* Delete the character under the cursor.  Given a numeric argument,
1448    kill that many characters instead. */
1449 int
1450 rl_delete (count, key)
1451      int count, key;
1452 {
1453   if (count < 0)
1454     return (rl_rubout (-count, key));
1455
1456   if (rl_point == rl_end)
1457     {
1458       ding ();
1459       return -1;
1460     }
1461
1462   if (count > 1 || rl_explicit_arg)
1463     {
1464       int orig_point = rl_point;
1465       rl_forward (count, key);
1466       rl_kill_text (orig_point, rl_point);
1467       rl_point = orig_point;
1468       return 0;
1469     }
1470   else
1471     return (rl_delete_text (rl_point, rl_point + 1));
1472 }
1473
1474 /* Delete the character under the cursor, unless the insertion
1475    point is at the end of the line, in which case the character
1476    behind the cursor is deleted.  COUNT is obeyed and may be used
1477    to delete forward or backward that many characters. */      
1478 int
1479 rl_rubout_or_delete (count, key)
1480      int count, key;
1481 {
1482   if (rl_end != 0 && rl_point == rl_end)
1483     return (rl_rubout (count, key));
1484   else
1485     return (rl_delete (count, key));
1486 }  
1487
1488 /* Delete all spaces and tabs around point. */
1489 int
1490 rl_delete_horizontal_space (count, ignore)
1491      int count, ignore;
1492 {
1493   int start = rl_point;
1494
1495   while (rl_point && whitespace (the_line[rl_point - 1]))
1496     rl_point--;
1497
1498   start = rl_point;
1499
1500   while (rl_point < rl_end && whitespace (the_line[rl_point]))
1501     rl_point++;
1502
1503   if (start != rl_point)
1504     {
1505       rl_delete_text (start, rl_point);
1506       rl_point = start;
1507     }
1508   return 0;
1509 }
1510
1511 /* Like the tcsh editing function delete-char-or-list.  The eof character
1512    is caught before this is invoked, so this really does the same thing as
1513    delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1514 int
1515 rl_delete_or_show_completions (count, key)
1516      int count, key;
1517 {
1518   if (rl_end != 0 && rl_point == rl_end)
1519     return (rl_possible_completions (count, key));
1520   else
1521     return (rl_delete (count, key));
1522 }
1523
1524 #ifndef RL_COMMENT_BEGIN_DEFAULT
1525 #define RL_COMMENT_BEGIN_DEFAULT "#"
1526 #endif
1527
1528 /* Turn the current line into a comment in shell history.
1529    A K*rn shell style function. */
1530 int
1531 rl_insert_comment (count, key)
1532      int count, key;
1533 {
1534   rl_beg_of_line (1, key);
1535   rl_insert_text (_rl_comment_begin ? _rl_comment_begin
1536                                     : RL_COMMENT_BEGIN_DEFAULT);
1537   (*rl_redisplay_function) ();
1538   rl_newline (1, '\n');
1539   return (0);
1540 }
1541
1542 /* **************************************************************** */
1543 /*                                                                  */
1544 /*                      Changing Case                               */
1545 /*                                                                  */
1546 /* **************************************************************** */
1547
1548 /* The three kinds of things that we know how to do. */
1549 #define UpCase 1
1550 #define DownCase 2
1551 #define CapCase 3
1552
1553 /* Uppercase the word at point. */
1554 int
1555 rl_upcase_word (count, key)
1556      int count, key;
1557 {
1558   return (rl_change_case (count, UpCase));
1559 }
1560
1561 /* Lowercase the word at point. */
1562 int
1563 rl_downcase_word (count, key)
1564      int count, key;
1565 {
1566   return (rl_change_case (count, DownCase));
1567 }
1568
1569 /* Upcase the first letter, downcase the rest. */
1570 int
1571 rl_capitalize_word (count, key)
1572      int count, key;
1573 {
1574  return (rl_change_case (count, CapCase));
1575 }
1576
1577 /* The meaty function.
1578    Change the case of COUNT words, performing OP on them.
1579    OP is one of UpCase, DownCase, or CapCase.
1580    If a negative argument is given, leave point where it started,
1581    otherwise, leave it where it moves to. */
1582 static int
1583 rl_change_case (count, op)
1584      int count, op;
1585 {
1586   register int start, end;
1587   int inword, c;
1588
1589   start = rl_point;
1590   rl_forward_word (count, 0);
1591   end = rl_point;
1592
1593   if (count < 0)
1594     SWAP (start, end);
1595
1596   /* We are going to modify some text, so let's prepare to undo it. */
1597   rl_modifying (start, end);
1598
1599   for (inword = 0; start < end; start++)
1600     {
1601       c = the_line[start];
1602       switch (op)
1603         {
1604         case UpCase:
1605           the_line[start] = _rl_to_upper (c);
1606           break;
1607
1608         case DownCase:
1609           the_line[start] = _rl_to_lower (c);
1610           break;
1611
1612         case CapCase:
1613           the_line[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
1614           inword = alphabetic (the_line[start]);
1615           break;
1616
1617         default:
1618           ding ();
1619           return -1;
1620         }
1621     }
1622   rl_point = end;
1623   return 0;
1624 }
1625
1626 /* **************************************************************** */
1627 /*                                                                  */
1628 /*                      Transposition                               */
1629 /*                                                                  */
1630 /* **************************************************************** */
1631
1632 /* Transpose the words at point. */
1633 int
1634 rl_transpose_words (count, key)
1635      int count, key;
1636 {
1637   char *word1, *word2;
1638   int w1_beg, w1_end, w2_beg, w2_end;
1639   int orig_point = rl_point;
1640
1641   if (!count)
1642     return 0;
1643
1644   /* Find the two words. */
1645   rl_forward_word (count, key);
1646   w2_end = rl_point;
1647   rl_backward_word (1, key);
1648   w2_beg = rl_point;
1649   rl_backward_word (count, key);
1650   w1_beg = rl_point;
1651   rl_forward_word (1, key);
1652   w1_end = rl_point;
1653
1654   /* Do some check to make sure that there really are two words. */
1655   if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1656     {
1657       ding ();
1658       rl_point = orig_point;
1659       return -1;
1660     }
1661
1662   /* Get the text of the words. */
1663   word1 = rl_copy_text (w1_beg, w1_end);
1664   word2 = rl_copy_text (w2_beg, w2_end);
1665
1666   /* We are about to do many insertions and deletions.  Remember them
1667      as one operation. */
1668   rl_begin_undo_group ();
1669
1670   /* Do the stuff at word2 first, so that we don't have to worry
1671      about word1 moving. */
1672   rl_point = w2_beg;
1673   rl_delete_text (w2_beg, w2_end);
1674   rl_insert_text (word1);
1675
1676   rl_point = w1_beg;
1677   rl_delete_text (w1_beg, w1_end);
1678   rl_insert_text (word2);
1679
1680   /* This is exactly correct since the text before this point has not
1681      changed in length. */
1682   rl_point = w2_end;
1683
1684   /* I think that does it. */
1685   rl_end_undo_group ();
1686   free (word1);
1687   free (word2);
1688
1689   return 0;
1690 }
1691
1692 /* Transpose the characters at point.  If point is at the end of the line,
1693    then transpose the characters before point. */
1694 int
1695 rl_transpose_chars (count, key)
1696      int count, key;
1697 {
1698   char dummy[2];
1699
1700   if (!count)
1701     return 0;
1702
1703   if (!rl_point || rl_end < 2)
1704     {
1705       ding ();
1706       return -1;
1707     }
1708
1709   rl_begin_undo_group ();
1710
1711   if (rl_point == rl_end)
1712     {
1713       --rl_point;
1714       count = 1;
1715     }
1716   rl_point--;
1717
1718   dummy[0] = the_line[rl_point];
1719   dummy[1] = '\0';
1720
1721   rl_delete_text (rl_point, rl_point + 1);
1722
1723   rl_point += count;
1724   _rl_fix_point (0);
1725   rl_insert_text (dummy);
1726
1727   rl_end_undo_group ();
1728   return 0;
1729 }
1730
1731 /* **************************************************************** */
1732 /*                                                                  */
1733 /*                      Character Searching                         */
1734 /*                                                                  */
1735 /* **************************************************************** */
1736
1737 int
1738 _rl_char_search_internal (count, dir, schar)
1739      int count, dir, schar;
1740 {
1741   int pos, inc;
1742
1743   pos = rl_point;
1744   inc = (dir < 0) ? -1 : 1;
1745   while (count)
1746     {
1747       if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1748         {
1749           ding ();
1750           return -1;
1751         }
1752
1753       pos += inc;
1754       do
1755         {
1756           if (rl_line_buffer[pos] == schar)
1757             {
1758               count--;
1759               if (dir < 0)
1760                 rl_point = (dir == BTO) ? pos + 1 : pos;
1761               else
1762                 rl_point = (dir == FTO) ? pos - 1 : pos;
1763               break;
1764             }
1765         }
1766       while ((dir < 0) ? pos-- : ++pos < rl_end);
1767     }
1768   return (0);
1769 }
1770
1771 /* Search COUNT times for a character read from the current input stream.
1772    FDIR is the direction to search if COUNT is non-negative; otherwise
1773    the search goes in BDIR. */
1774 static int
1775 _rl_char_search (count, fdir, bdir)
1776      int count, fdir, bdir;
1777 {
1778   int c;
1779
1780   c = rl_read_key ();
1781   if (count < 0)
1782     return (_rl_char_search_internal (-count, bdir, c));
1783   else
1784     return (_rl_char_search_internal (count, fdir, c));
1785 }
1786
1787 int
1788 rl_char_search (count, key)
1789      int count, key;
1790 {
1791   return (_rl_char_search (count, FFIND, BFIND));
1792 }
1793
1794 int
1795 rl_backward_char_search (count, key)
1796      int count, key;
1797 {
1798   return (_rl_char_search (count, BFIND, FFIND));
1799 }
1800
1801 /* **************************************************************** */
1802 /*                                                                  */
1803 /*                      History Utilities                           */
1804 /*                                                                  */
1805 /* **************************************************************** */
1806
1807 /* We already have a history library, and that is what we use to control
1808    the history features of readline.  This is our local interface to
1809    the history mechanism. */
1810
1811 /* While we are editing the history, this is the saved
1812    version of the original line. */
1813 HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
1814
1815 /* Set the history pointer back to the last entry in the history. */
1816 static void
1817 start_using_history ()
1818 {
1819   using_history ();
1820   if (saved_line_for_history)
1821     _rl_free_history_entry (saved_line_for_history);
1822
1823   saved_line_for_history = (HIST_ENTRY *)NULL;
1824 }
1825
1826 /* Free the contents (and containing structure) of a HIST_ENTRY. */
1827 void
1828 _rl_free_history_entry (entry)
1829      HIST_ENTRY *entry;
1830 {
1831   if (entry == 0)
1832     return;
1833   if (entry->line)
1834     free (entry->line);
1835   free (entry);
1836 }
1837
1838 /* Perhaps put back the current line if it has changed. */
1839 int
1840 maybe_replace_line ()
1841 {
1842   HIST_ENTRY *temp;
1843
1844   temp = current_history ();
1845   /* If the current line has changed, save the changes. */
1846   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
1847     {
1848       temp = replace_history_entry (where_history (), the_line, (histdata_t)rl_undo_list);
1849       free (temp->line);
1850       free (temp);
1851     }
1852   return 0;
1853 }
1854
1855 /* Put back the saved_line_for_history if there is one. */
1856 int
1857 maybe_unsave_line ()
1858 {
1859   int line_len;
1860
1861   if (saved_line_for_history)
1862     {
1863       line_len = strlen (saved_line_for_history->line);
1864
1865       if (line_len >= rl_line_buffer_len)
1866         rl_extend_line_buffer (line_len);
1867
1868       strcpy (the_line, saved_line_for_history->line);
1869       rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
1870       _rl_free_history_entry (saved_line_for_history);
1871       saved_line_for_history = (HIST_ENTRY *)NULL;
1872       rl_end = rl_point = strlen (the_line);
1873     }
1874   else
1875     ding ();
1876   return 0;
1877 }
1878
1879 /* Save the current line in saved_line_for_history. */
1880 int
1881 maybe_save_line ()
1882 {
1883   if (saved_line_for_history == 0)
1884     {
1885       saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
1886       saved_line_for_history->line = savestring (the_line);
1887       saved_line_for_history->data = (char *)rl_undo_list;
1888     }
1889   return 0;
1890 }
1891
1892 /* **************************************************************** */
1893 /*                                                                  */
1894 /*                      History Commands                            */
1895 /*                                                                  */
1896 /* **************************************************************** */
1897
1898 /* Meta-< goes to the start of the history. */
1899 int
1900 rl_beginning_of_history (count, key)
1901      int count, key;
1902 {
1903   return (rl_get_previous_history (1 + where_history (), key));
1904 }
1905
1906 /* Meta-> goes to the end of the history.  (The current line). */
1907 int
1908 rl_end_of_history (count, key)
1909      int count, key;
1910 {
1911   maybe_replace_line ();
1912   using_history ();
1913   maybe_unsave_line ();
1914   return 0;
1915 }
1916
1917 /* Move down to the next history line. */
1918 int
1919 rl_get_next_history (count, key)
1920      int count, key;
1921 {
1922   HIST_ENTRY *temp;
1923   int line_len;
1924
1925   if (count < 0)
1926     return (rl_get_previous_history (-count, key));
1927
1928   if (count == 0)
1929     return 0;
1930
1931   maybe_replace_line ();
1932
1933   temp = (HIST_ENTRY *)NULL;
1934   while (count)
1935     {
1936       temp = next_history ();
1937       if (!temp)
1938         break;
1939       --count;
1940     }
1941
1942   if (temp == 0)
1943     maybe_unsave_line ();
1944   else
1945     {
1946       line_len = strlen (temp->line);
1947
1948       if (line_len >= rl_line_buffer_len)
1949         rl_extend_line_buffer (line_len);
1950
1951       strcpy (the_line, temp->line);
1952       rl_undo_list = (UNDO_LIST *)temp->data;
1953       rl_end = rl_point = strlen (the_line);
1954 #if defined (VI_MODE)
1955       if (rl_editing_mode == vi_mode)
1956         rl_point = 0;
1957 #endif /* VI_MODE */
1958     }
1959   return 0;
1960 }
1961
1962 /* Get the previous item out of our interactive history, making it the current
1963    line.  If there is no previous history, just ding. */
1964 int
1965 rl_get_previous_history (count, key)
1966      int count, key;
1967 {
1968   HIST_ENTRY *old_temp, *temp;
1969   int line_len;
1970
1971   if (count < 0)
1972     return (rl_get_next_history (-count, key));
1973
1974   if (count == 0)
1975     return 0;
1976
1977   /* If we don't have a line saved, then save this one. */
1978   maybe_save_line ();
1979
1980   /* If the current line has changed, save the changes. */
1981   maybe_replace_line ();
1982
1983   temp = old_temp = (HIST_ENTRY *)NULL;
1984   while (count)
1985     {
1986       temp = previous_history ();
1987       if (temp == 0)
1988         break;
1989
1990       old_temp = temp;
1991       --count;
1992     }
1993
1994   /* If there was a large argument, and we moved back to the start of the
1995      history, that is not an error.  So use the last value found. */
1996   if (!temp && old_temp)
1997     temp = old_temp;
1998
1999   if (temp == 0)
2000     ding ();
2001   else
2002     {
2003       line_len = strlen (temp->line);
2004
2005       if (line_len >= rl_line_buffer_len)
2006         rl_extend_line_buffer (line_len);
2007
2008       strcpy (the_line, temp->line);
2009       rl_undo_list = (UNDO_LIST *)temp->data;
2010       rl_end = rl_point = line_len;
2011
2012 #if defined (VI_MODE)
2013       if (rl_editing_mode == vi_mode)
2014         rl_point = 0;
2015 #endif /* VI_MODE */
2016     }
2017   return 0;
2018 }
2019
2020 /* **************************************************************** */
2021 /*                                                                  */
2022 /*                 The Mark and the Region.                         */
2023 /*                                                                  */
2024 /* **************************************************************** */
2025
2026 /* Set the mark at POSITION. */
2027 int
2028 _rl_set_mark_at_pos (position)
2029      int position;
2030 {
2031   if (position > rl_end)
2032     return -1;
2033
2034   rl_mark = position;
2035   return 0;
2036 }
2037
2038 /* A bindable command to set the mark. */
2039 int
2040 rl_set_mark (count, key)
2041      int count, key;
2042 {
2043   return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
2044 }
2045
2046 /* Exchange the position of mark and point. */
2047 int
2048 rl_exchange_point_and_mark (count, key)
2049      int count, key;
2050 {
2051   if (rl_mark > rl_end)
2052     rl_mark = -1;
2053
2054   if (rl_mark == -1)
2055     {
2056       ding ();
2057       return -1;
2058     }
2059   else
2060     SWAP (rl_point, rl_mark);
2061
2062   return 0;
2063 }
2064
2065 /* **************************************************************** */
2066 /*                                                                  */
2067 /*                          Editing Modes                           */
2068 /*                                                                  */
2069 /* **************************************************************** */
2070 /* How to toggle back and forth between editing modes. */
2071 int
2072 rl_vi_editing_mode (count, key)
2073      int count, key;
2074 {
2075 #if defined (VI_MODE)
2076   rl_editing_mode = vi_mode;
2077   rl_vi_insertion_mode (1, key);
2078 #endif /* VI_MODE */
2079   return 0;
2080 }
2081
2082 int
2083 rl_emacs_editing_mode (count, key)
2084      int count, key;
2085 {
2086   rl_editing_mode = emacs_mode;
2087   _rl_keymap = emacs_standard_keymap;
2088   return 0;
2089 }