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