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