Add missing space.
[binutils-gdb.git] / readline / text.c
blobbb87604aa6d4b286d9cc67de8503b5277963d3ec
1 /* text.c -- text handling commands for readline. */
3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
8 The GNU Readline Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2, or
11 (at your option) any later version.
13 The GNU Readline Library is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22 #define READLINE_LIBRARY
24 #if defined (HAVE_CONFIG_H)
25 # include <config.h>
26 #endif
28 #if defined (HAVE_UNISTD_H)
29 # include <unistd.h>
30 #endif /* HAVE_UNISTD_H */
32 #if defined (HAVE_STDLIB_H)
33 # include <stdlib.h>
34 #else
35 # include "ansi_stdlib.h"
36 #endif /* HAVE_STDLIB_H */
38 #if defined (HAVE_LOCALE_H)
39 # include <locale.h>
40 #endif
42 #include <stdio.h>
44 /* System-specific feature definitions and include files. */
45 #include "rldefs.h"
46 #include "rlmbutil.h"
48 #if defined (__EMX__)
49 # define INCL_DOSPROCESS
50 # include <os2.h>
51 #endif /* __EMX__ */
53 /* Some standard library routines. */
54 #include "readline.h"
55 #include "history.h"
57 #include "rlprivate.h"
58 #include "rlshell.h"
59 #include "xmalloc.h"
61 /* Forward declarations. */
62 static int rl_change_case PARAMS((int, int));
63 static int _rl_char_search PARAMS((int, int, int));
65 #if defined (READLINE_CALLBACKS)
66 static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
67 static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
68 #endif
70 /* **************************************************************** */
71 /* */
72 /* Insert and Delete */
73 /* */
74 /* **************************************************************** */
76 /* Insert a string of text into the line at point. This is the only
77 way that you should do insertion. _rl_insert_char () calls this
78 function. Returns the number of characters inserted. */
79 int
80 rl_insert_text (string)
81 const char *string;
83 register int i, l;
85 l = (string && *string) ? strlen (string) : 0;
86 if (l == 0)
87 return 0;
89 if (rl_end + l >= rl_line_buffer_len)
90 rl_extend_line_buffer (rl_end + l);
92 for (i = rl_end; i >= rl_point; i--)
93 rl_line_buffer[i + l] = rl_line_buffer[i];
94 strncpy (rl_line_buffer + rl_point, string, l);
96 /* Remember how to undo this if we aren't undoing something. */
97 if (_rl_doing_an_undo == 0)
99 /* If possible and desirable, concatenate the undos. */
100 if ((l == 1) &&
101 rl_undo_list &&
102 (rl_undo_list->what == UNDO_INSERT) &&
103 (rl_undo_list->end == rl_point) &&
104 (rl_undo_list->end - rl_undo_list->start < 20))
105 rl_undo_list->end++;
106 else
107 rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
109 rl_point += l;
110 rl_end += l;
111 rl_line_buffer[rl_end] = '\0';
112 return l;
115 /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
116 Returns the number of characters deleted. */
118 rl_delete_text (from, to)
119 int from, to;
121 register char *text;
122 register int diff, i;
124 /* Fix it if the caller is confused. */
125 if (from > to)
126 SWAP (from, to);
128 /* fix boundaries */
129 if (to > rl_end)
131 to = rl_end;
132 if (from > to)
133 from = to;
135 if (from < 0)
136 from = 0;
138 text = rl_copy_text (from, to);
140 /* Some versions of strncpy() can't handle overlapping arguments. */
141 diff = to - from;
142 for (i = from; i < rl_end - diff; i++)
143 rl_line_buffer[i] = rl_line_buffer[i + diff];
145 /* Remember how to undo this delete. */
146 if (_rl_doing_an_undo == 0)
147 rl_add_undo (UNDO_DELETE, from, to, text);
148 else
149 free (text);
151 rl_end -= diff;
152 rl_line_buffer[rl_end] = '\0';
153 return (diff);
156 /* Fix up point so that it is within the line boundaries after killing
157 text. If FIX_MARK_TOO is non-zero, the mark is forced within line
158 boundaries also. */
160 #define _RL_FIX_POINT(x) \
161 do { \
162 if (x > rl_end) \
163 x = rl_end; \
164 else if (x < 0) \
165 x = 0; \
166 } while (0)
168 void
169 _rl_fix_point (fix_mark_too)
170 int fix_mark_too;
172 _RL_FIX_POINT (rl_point);
173 if (fix_mark_too)
174 _RL_FIX_POINT (rl_mark);
176 #undef _RL_FIX_POINT
178 /* Replace the contents of the line buffer between START and END with
179 TEXT. The operation is undoable. To replace the entire line in an
180 undoable mode, use _rl_replace_text(text, 0, rl_end); */
182 _rl_replace_text (text, start, end)
183 const char *text;
184 int start, end;
186 int n;
188 rl_begin_undo_group ();
189 rl_delete_text (start, end + 1);
190 rl_point = start;
191 n = rl_insert_text (text);
192 rl_end_undo_group ();
194 return n;
197 /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
198 non-zero, we free the current undo list. */
199 void
200 rl_replace_line (text, clear_undo)
201 const char *text;
202 int clear_undo;
204 int len;
206 len = strlen (text);
207 if (len >= rl_line_buffer_len)
208 rl_extend_line_buffer (len);
209 strcpy (rl_line_buffer, text);
210 rl_end = len;
212 if (clear_undo)
213 rl_free_undo_list ();
215 _rl_fix_point (1);
218 /* **************************************************************** */
219 /* */
220 /* Readline character functions */
221 /* */
222 /* **************************************************************** */
224 /* This is not a gap editor, just a stupid line input routine. No hair
225 is involved in writing any of the functions, and none should be. */
227 /* Note that:
229 rl_end is the place in the string that we would place '\0';
230 i.e., it is always safe to place '\0' there.
232 rl_point is the place in the string where the cursor is. Sometimes
233 this is the same as rl_end.
235 Any command that is called interactively receives two arguments.
236 The first is a count: the numeric arg pased to this command.
237 The second is the key which invoked this command.
240 /* **************************************************************** */
241 /* */
242 /* Movement Commands */
243 /* */
244 /* **************************************************************** */
246 /* Note that if you `optimize' the display for these functions, you cannot
247 use said functions in other functions which do not do optimizing display.
248 I.e., you will have to update the data base for rl_redisplay, and you
249 might as well let rl_redisplay do that job. */
251 /* Move forward COUNT bytes. */
253 rl_forward_byte (count, key)
254 int count, key;
256 if (count < 0)
257 return (rl_backward_byte (-count, key));
259 if (count > 0)
261 int end = rl_point + count;
262 #if defined (VI_MODE)
263 int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
264 #else
265 int lend = rl_end;
266 #endif
268 if (end > lend)
270 rl_point = lend;
271 rl_ding ();
273 else
274 rl_point = end;
277 if (rl_end < 0)
278 rl_end = 0;
280 return 0;
283 #if defined (HANDLE_MULTIBYTE)
284 /* Move forward COUNT characters. */
286 rl_forward_char (count, key)
287 int count, key;
289 int point;
291 if (MB_CUR_MAX == 1 || rl_byte_oriented)
292 return (rl_forward_byte (count, key));
294 if (count < 0)
295 return (rl_backward_char (-count, key));
297 if (count > 0)
299 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
301 #if defined (VI_MODE)
302 if (rl_end <= point && rl_editing_mode == vi_mode)
303 point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
304 #endif
306 if (rl_point == point)
307 rl_ding ();
309 rl_point = point;
311 if (rl_end < 0)
312 rl_end = 0;
315 return 0;
317 #else /* !HANDLE_MULTIBYTE */
319 rl_forward_char (count, key)
320 int count, key;
322 return (rl_forward_byte (count, key));
324 #endif /* !HANDLE_MULTIBYTE */
326 /* Backwards compatibility. */
328 rl_forward (count, key)
329 int count, key;
331 return (rl_forward_char (count, key));
334 /* Move backward COUNT bytes. */
336 rl_backward_byte (count, key)
337 int count, key;
339 if (count < 0)
340 return (rl_forward_byte (-count, key));
342 if (count > 0)
344 if (rl_point < count)
346 rl_point = 0;
347 rl_ding ();
349 else
350 rl_point -= count;
353 if (rl_point < 0)
354 rl_point = 0;
356 return 0;
359 #if defined (HANDLE_MULTIBYTE)
360 /* Move backward COUNT characters. */
362 rl_backward_char (count, key)
363 int count, key;
365 int point;
367 if (MB_CUR_MAX == 1 || rl_byte_oriented)
368 return (rl_backward_byte (count, key));
370 if (count < 0)
371 return (rl_forward_char (-count, key));
373 if (count > 0)
375 point = rl_point;
377 while (count > 0 && point > 0)
379 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
380 count--;
382 if (count > 0)
384 rl_point = 0;
385 rl_ding ();
387 else
388 rl_point = point;
391 return 0;
393 #else
395 rl_backward_char (count, key)
396 int count, key;
398 return (rl_backward_byte (count, key));
400 #endif
402 /* Backwards compatibility. */
404 rl_backward (count, key)
405 int count, key;
407 return (rl_backward_char (count, key));
410 /* Move to the beginning of the line. */
412 rl_beg_of_line (count, key)
413 int count, key;
415 rl_point = 0;
416 return 0;
419 /* Move to the end of the line. */
421 rl_end_of_line (count, key)
422 int count, key;
424 rl_point = rl_end;
425 return 0;
428 /* Move forward a word. We do what Emacs does. Handles multibyte chars. */
430 rl_forward_word (count, key)
431 int count, key;
433 int c;
435 if (count < 0)
436 return (rl_backward_word (-count, key));
438 while (count)
440 if (rl_point == rl_end)
441 return 0;
443 /* If we are not in a word, move forward until we are in one.
444 Then, move forward until we hit a non-alphabetic character. */
445 c = _rl_char_value (rl_line_buffer, rl_point);
447 if (_rl_walphabetic (c) == 0)
449 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
450 while (rl_point < rl_end)
452 c = _rl_char_value (rl_line_buffer, rl_point);
453 if (_rl_walphabetic (c))
454 break;
455 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
459 if (rl_point == rl_end)
460 return 0;
462 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
463 while (rl_point < rl_end)
465 c = _rl_char_value (rl_line_buffer, rl_point);
466 if (_rl_walphabetic (c) == 0)
467 break;
468 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
471 --count;
474 return 0;
477 /* Move backward a word. We do what Emacs does. Handles multibyte chars. */
479 rl_backward_word (count, key)
480 int count, key;
482 int c, p;
484 if (count < 0)
485 return (rl_forward_word (-count, key));
487 while (count)
489 if (rl_point == 0)
490 return 0;
492 /* Like rl_forward_word (), except that we look at the characters
493 just before point. */
495 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
496 c = _rl_char_value (rl_line_buffer, p);
498 if (_rl_walphabetic (c) == 0)
500 rl_point = p;
501 while (rl_point > 0)
503 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
504 c = _rl_char_value (rl_line_buffer, p);
505 if (_rl_walphabetic (c))
506 break;
507 rl_point = p;
511 while (rl_point)
513 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
514 c = _rl_char_value (rl_line_buffer, p);
515 if (_rl_walphabetic (c) == 0)
516 break;
517 else
518 rl_point = p;
521 --count;
524 return 0;
527 /* Clear the current line. Numeric argument to C-l does this. */
529 rl_refresh_line (ignore1, ignore2)
530 int ignore1, ignore2;
532 int curr_line;
534 curr_line = _rl_current_display_line ();
536 _rl_move_vert (curr_line);
537 _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
539 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
541 rl_forced_update_display ();
542 rl_display_fixed = 1;
544 return 0;
547 /* C-l typed to a line without quoting clears the screen, and then reprints
548 the prompt and the current input line. Given a numeric arg, redraw only
549 the current line. */
551 rl_clear_screen (count, key)
552 int count, key;
554 if (rl_explicit_arg)
556 rl_refresh_line (count, key);
557 return 0;
560 _rl_clear_screen (); /* calls termcap function to clear screen */
561 rl_forced_update_display ();
562 rl_display_fixed = 1;
564 return 0;
568 rl_arrow_keys (count, c)
569 int count, c;
571 int ch;
573 RL_SETSTATE(RL_STATE_MOREINPUT);
574 ch = rl_read_key ();
575 RL_UNSETSTATE(RL_STATE_MOREINPUT);
577 switch (_rl_to_upper (ch))
579 case 'A':
580 rl_get_previous_history (count, ch);
581 break;
583 case 'B':
584 rl_get_next_history (count, ch);
585 break;
587 case 'C':
588 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
589 rl_forward_char (count, ch);
590 else
591 rl_forward_byte (count, ch);
592 break;
594 case 'D':
595 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
596 rl_backward_char (count, ch);
597 else
598 rl_backward_byte (count, ch);
599 break;
601 default:
602 rl_ding ();
605 return 0;
608 /* **************************************************************** */
609 /* */
610 /* Text commands */
611 /* */
612 /* **************************************************************** */
614 #ifdef HANDLE_MULTIBYTE
615 static char pending_bytes[MB_LEN_MAX];
616 static int pending_bytes_length = 0;
617 static mbstate_t ps = {0};
618 #endif
620 /* Insert the character C at the current location, moving point forward.
621 If C introduces a multibyte sequence, we read the whole sequence and
622 then insert the multibyte char into the line buffer. */
624 _rl_insert_char (count, c)
625 int count, c;
627 register int i;
628 char *string;
629 #ifdef HANDLE_MULTIBYTE
630 int string_size;
631 char incoming[MB_LEN_MAX + 1];
632 int incoming_length = 0;
633 mbstate_t ps_back;
634 static int stored_count = 0;
635 #endif
637 if (count <= 0)
638 return 0;
640 #if defined (HANDLE_MULTIBYTE)
641 if (MB_CUR_MAX == 1 || rl_byte_oriented)
643 incoming[0] = c;
644 incoming[1] = '\0';
645 incoming_length = 1;
647 else
649 wchar_t wc;
650 size_t ret;
652 if (stored_count <= 0)
653 stored_count = count;
654 else
655 count = stored_count;
657 ps_back = ps;
658 pending_bytes[pending_bytes_length++] = c;
659 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
661 if (ret == (size_t)-2)
663 /* Bytes too short to compose character, try to wait for next byte.
664 Restore the state of the byte sequence, because in this case the
665 effect of mbstate is undefined. */
666 ps = ps_back;
667 return 1;
669 else if (ret == (size_t)-1)
671 /* Invalid byte sequence for the current locale. Treat first byte
672 as a single character. */
673 incoming[0] = pending_bytes[0];
674 incoming[1] = '\0';
675 incoming_length = 1;
676 pending_bytes_length--;
677 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
678 /* Clear the state of the byte sequence, because in this case the
679 effect of mbstate is undefined. */
680 memset (&ps, 0, sizeof (mbstate_t));
682 else if (ret == (size_t)0)
684 incoming[0] = '\0';
685 incoming_length = 0;
686 pending_bytes_length--;
687 /* Clear the state of the byte sequence, because in this case the
688 effect of mbstate is undefined. */
689 memset (&ps, 0, sizeof (mbstate_t));
691 else
693 /* We successfully read a single multibyte character. */
694 memcpy (incoming, pending_bytes, pending_bytes_length);
695 incoming[pending_bytes_length] = '\0';
696 incoming_length = pending_bytes_length;
697 pending_bytes_length = 0;
700 #endif /* HANDLE_MULTIBYTE */
702 /* If we can optimize, then do it. But don't let people crash
703 readline because of extra large arguments. */
704 if (count > 1 && count <= 1024)
706 #if defined (HANDLE_MULTIBYTE)
707 string_size = count * incoming_length;
708 string = (char *)xmalloc (1 + string_size);
710 i = 0;
711 while (i < string_size)
713 strncpy (string + i, incoming, incoming_length);
714 i += incoming_length;
716 incoming_length = 0;
717 stored_count = 0;
718 #else /* !HANDLE_MULTIBYTE */
719 string = (char *)xmalloc (1 + count);
721 for (i = 0; i < count; i++)
722 string[i] = c;
723 #endif /* !HANDLE_MULTIBYTE */
725 string[i] = '\0';
726 rl_insert_text (string);
727 free (string);
729 return 0;
732 if (count > 1024)
734 int decreaser;
735 #if defined (HANDLE_MULTIBYTE)
736 string_size = incoming_length * 1024;
737 string = (char *)xmalloc (1 + string_size);
739 i = 0;
740 while (i < string_size)
742 strncpy (string + i, incoming, incoming_length);
743 i += incoming_length;
746 while (count)
748 decreaser = (count > 1024) ? 1024 : count;
749 string[decreaser*incoming_length] = '\0';
750 rl_insert_text (string);
751 count -= decreaser;
754 free (string);
755 incoming_length = 0;
756 stored_count = 0;
757 #else /* !HANDLE_MULTIBYTE */
758 char str[1024+1];
760 for (i = 0; i < 1024; i++)
761 str[i] = c;
763 while (count)
765 decreaser = (count > 1024 ? 1024 : count);
766 str[decreaser] = '\0';
767 rl_insert_text (str);
768 count -= decreaser;
770 #endif /* !HANDLE_MULTIBYTE */
772 return 0;
775 if (MB_CUR_MAX == 1 || rl_byte_oriented)
777 /* We are inserting a single character.
778 If there is pending input, then make a string of all of the
779 pending characters that are bound to rl_insert, and insert
780 them all. */
781 if (_rl_any_typein ())
782 _rl_insert_typein (c);
783 else
785 /* Inserting a single character. */
786 char str[2];
788 str[1] = '\0';
789 str[0] = c;
790 rl_insert_text (str);
793 #if defined (HANDLE_MULTIBYTE)
794 else
796 rl_insert_text (incoming);
797 stored_count = 0;
799 #endif
801 return 0;
804 /* Overwrite the character at point (or next COUNT characters) with C.
805 If C introduces a multibyte character sequence, read the entire sequence
806 before starting the overwrite loop. */
808 _rl_overwrite_char (count, c)
809 int count, c;
811 int i;
812 #if defined (HANDLE_MULTIBYTE)
813 char mbkey[MB_LEN_MAX];
814 int k;
816 /* Read an entire multibyte character sequence to insert COUNT times. */
817 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
818 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
819 #endif
821 rl_begin_undo_group ();
823 for (i = 0; i < count; i++)
825 #if defined (HANDLE_MULTIBYTE)
826 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
827 rl_insert_text (mbkey);
828 else
829 #endif
830 _rl_insert_char (1, c);
832 if (rl_point < rl_end)
833 rl_delete (1, c);
836 rl_end_undo_group ();
838 return 0;
842 rl_insert (count, c)
843 int count, c;
845 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
846 : _rl_overwrite_char (count, c));
849 /* Insert the next typed character verbatim. */
850 static int
851 _rl_insert_next (count)
852 int count;
854 int c;
856 RL_SETSTATE(RL_STATE_MOREINPUT);
857 c = rl_read_key ();
858 RL_UNSETSTATE(RL_STATE_MOREINPUT);
860 #if defined (HANDLE_SIGNALS)
861 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
862 _rl_restore_tty_signals ();
863 #endif
865 return (_rl_insert_char (count, c));
868 #if defined (READLINE_CALLBACKS)
869 static int
870 _rl_insert_next_callback (data)
871 _rl_callback_generic_arg *data;
873 int count;
875 count = data->count;
877 /* Deregister function, let rl_callback_read_char deallocate data */
878 _rl_callback_func = 0;
879 _rl_want_redisplay = 1;
881 return _rl_insert_next (count);
883 #endif
886 rl_quoted_insert (count, key)
887 int count, key;
889 /* Let's see...should the callback interface futz with signal handling? */
890 #if defined (HANDLE_SIGNALS)
891 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
892 _rl_disable_tty_signals ();
893 #endif
895 #if defined (READLINE_CALLBACKS)
896 if (RL_ISSTATE (RL_STATE_CALLBACK))
898 _rl_callback_data = _rl_callback_data_alloc (count);
899 _rl_callback_func = _rl_insert_next_callback;
900 return (0);
902 #endif
904 return _rl_insert_next (count);
907 /* Insert a tab character. */
909 rl_tab_insert (count, key)
910 int count, key;
912 return (_rl_insert_char (count, '\t'));
915 /* What to do when a NEWLINE is pressed. We accept the whole line.
916 KEY is the key that invoked this command. I guess it could have
917 meaning in the future. */
919 rl_newline (count, key)
920 int count, key;
922 rl_done = 1;
924 if (_rl_history_preserve_point)
925 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
927 RL_SETSTATE(RL_STATE_DONE);
929 #if defined (VI_MODE)
930 if (rl_editing_mode == vi_mode)
932 _rl_vi_done_inserting ();
933 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
934 _rl_vi_reset_last ();
936 #endif /* VI_MODE */
938 /* If we've been asked to erase empty lines, suppress the final update,
939 since _rl_update_final calls rl_crlf(). */
940 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
941 return 0;
943 if (readline_echoing_p)
944 _rl_update_final ();
945 return 0;
948 /* What to do for some uppercase characters, like meta characters,
949 and some characters appearing in emacs_ctlx_keymap. This function
950 is just a stub, you bind keys to it and the code in _rl_dispatch ()
951 is special cased. */
953 rl_do_lowercase_version (ignore1, ignore2)
954 int ignore1, ignore2;
956 return 0;
959 /* This is different from what vi does, so the code's not shared. Emacs
960 rubout in overwrite mode has one oddity: it replaces a control
961 character that's displayed as two characters (^X) with two spaces. */
963 _rl_overwrite_rubout (count, key)
964 int count, key;
966 int opoint;
967 int i, l;
969 if (rl_point == 0)
971 rl_ding ();
972 return 1;
975 opoint = rl_point;
977 /* L == number of spaces to insert */
978 for (i = l = 0; i < count; i++)
980 rl_backward_char (1, key);
981 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
984 rl_begin_undo_group ();
986 if (count > 1 || rl_explicit_arg)
987 rl_kill_text (opoint, rl_point);
988 else
989 rl_delete_text (opoint, rl_point);
991 /* Emacs puts point at the beginning of the sequence of spaces. */
992 if (rl_point < rl_end)
994 opoint = rl_point;
995 _rl_insert_char (l, ' ');
996 rl_point = opoint;
999 rl_end_undo_group ();
1001 return 0;
1004 /* Rubout the character behind point. */
1006 rl_rubout (count, key)
1007 int count, key;
1009 if (count < 0)
1010 return (rl_delete (-count, key));
1012 if (!rl_point)
1014 rl_ding ();
1015 return -1;
1018 if (rl_insert_mode == RL_IM_OVERWRITE)
1019 return (_rl_overwrite_rubout (count, key));
1021 return (_rl_rubout_char (count, key));
1025 _rl_rubout_char (count, key)
1026 int count, key;
1028 int orig_point;
1029 unsigned char c;
1031 /* Duplicated code because this is called from other parts of the library. */
1032 if (count < 0)
1033 return (rl_delete (-count, key));
1035 if (rl_point == 0)
1037 rl_ding ();
1038 return -1;
1041 orig_point = rl_point;
1042 if (count > 1 || rl_explicit_arg)
1044 rl_backward_char (count, key);
1045 rl_kill_text (orig_point, rl_point);
1047 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1049 c = rl_line_buffer[--rl_point];
1050 rl_delete_text (rl_point, orig_point);
1051 /* The erase-at-end-of-line hack is of questionable merit now. */
1052 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
1054 int l;
1055 l = rl_character_len (c, rl_point);
1056 _rl_erase_at_end_of_line (l);
1059 else
1061 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1062 rl_delete_text (rl_point, orig_point);
1065 return 0;
1068 /* Delete the character under the cursor. Given a numeric argument,
1069 kill that many characters instead. */
1071 rl_delete (count, key)
1072 int count, key;
1074 if (count < 0)
1075 return (_rl_rubout_char (-count, key));
1077 if (rl_point == rl_end)
1079 rl_ding ();
1080 return -1;
1083 if (count > 1 || rl_explicit_arg)
1085 int orig_point = rl_point;
1086 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1087 rl_forward_char (count, key);
1088 else
1089 rl_forward_byte (count, key);
1091 rl_kill_text (orig_point, rl_point);
1092 rl_point = orig_point;
1094 else
1096 int new_point;
1098 new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1099 rl_delete_text (rl_point, new_point);
1101 return 0;
1104 /* Delete the character under the cursor, unless the insertion
1105 point is at the end of the line, in which case the character
1106 behind the cursor is deleted. COUNT is obeyed and may be used
1107 to delete forward or backward that many characters. */
1109 rl_rubout_or_delete (count, key)
1110 int count, key;
1112 if (rl_end != 0 && rl_point == rl_end)
1113 return (_rl_rubout_char (count, key));
1114 else
1115 return (rl_delete (count, key));
1118 /* Delete all spaces and tabs around point. */
1120 rl_delete_horizontal_space (count, ignore)
1121 int count, ignore;
1123 int start = rl_point;
1125 while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1126 rl_point--;
1128 start = rl_point;
1130 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1131 rl_point++;
1133 if (start != rl_point)
1135 rl_delete_text (start, rl_point);
1136 rl_point = start;
1139 if (rl_point < 0)
1140 rl_point = 0;
1142 return 0;
1145 /* Like the tcsh editing function delete-char-or-list. The eof character
1146 is caught before this is invoked, so this really does the same thing as
1147 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1149 rl_delete_or_show_completions (count, key)
1150 int count, key;
1152 if (rl_end != 0 && rl_point == rl_end)
1153 return (rl_possible_completions (count, key));
1154 else
1155 return (rl_delete (count, key));
1158 #ifndef RL_COMMENT_BEGIN_DEFAULT
1159 #define RL_COMMENT_BEGIN_DEFAULT "#"
1160 #endif
1162 /* Turn the current line into a comment in shell history.
1163 A K*rn shell style function. */
1165 rl_insert_comment (count, key)
1166 int count, key;
1168 char *rl_comment_text;
1169 int rl_comment_len;
1171 rl_beg_of_line (1, key);
1172 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1174 if (rl_explicit_arg == 0)
1175 rl_insert_text (rl_comment_text);
1176 else
1178 rl_comment_len = strlen (rl_comment_text);
1179 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1180 rl_delete_text (rl_point, rl_point + rl_comment_len);
1181 else
1182 rl_insert_text (rl_comment_text);
1185 (*rl_redisplay_function) ();
1186 rl_newline (1, '\n');
1188 return (0);
1191 /* **************************************************************** */
1192 /* */
1193 /* Changing Case */
1194 /* */
1195 /* **************************************************************** */
1197 /* The three kinds of things that we know how to do. */
1198 #define UpCase 1
1199 #define DownCase 2
1200 #define CapCase 3
1202 /* Uppercase the word at point. */
1204 rl_upcase_word (count, key)
1205 int count, key;
1207 return (rl_change_case (count, UpCase));
1210 /* Lowercase the word at point. */
1212 rl_downcase_word (count, key)
1213 int count, key;
1215 return (rl_change_case (count, DownCase));
1218 /* Upcase the first letter, downcase the rest. */
1220 rl_capitalize_word (count, key)
1221 int count, key;
1223 return (rl_change_case (count, CapCase));
1226 /* The meaty function.
1227 Change the case of COUNT words, performing OP on them.
1228 OP is one of UpCase, DownCase, or CapCase.
1229 If a negative argument is given, leave point where it started,
1230 otherwise, leave it where it moves to. */
1231 static int
1232 rl_change_case (count, op)
1233 int count, op;
1235 int start, next, end;
1236 int inword, c, nc, nop;
1237 #if defined (HANDLE_MULTIBYTE)
1238 wchar_t wc, nwc;
1239 char mb[MB_LEN_MAX+1];
1240 int mblen, p;
1241 mbstate_t ps;
1242 #endif
1244 start = rl_point;
1245 rl_forward_word (count, 0);
1246 end = rl_point;
1248 if (op != UpCase && op != DownCase && op != CapCase)
1250 rl_ding ();
1251 return -1;
1254 if (count < 0)
1255 SWAP (start, end);
1257 #if defined (HANDLE_MULTIBYTE)
1258 memset (&ps, 0, sizeof (mbstate_t));
1259 #endif
1261 /* We are going to modify some text, so let's prepare to undo it. */
1262 rl_modifying (start, end);
1264 inword = 0;
1265 while (start < end)
1267 c = _rl_char_value (rl_line_buffer, start);
1268 /* This assumes that the upper and lower case versions are the same width. */
1269 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1271 if (_rl_walphabetic (c) == 0)
1273 inword = 0;
1274 start = next;
1275 continue;
1278 if (op == CapCase)
1280 nop = inword ? DownCase : UpCase;
1281 inword = 1;
1283 else
1284 nop = op;
1285 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
1287 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
1288 rl_line_buffer[start] = nc;
1290 #if defined (HANDLE_MULTIBYTE)
1291 else
1293 mbrtowc (&wc, rl_line_buffer + start, end - start, &ps);
1294 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1295 if (nwc != wc) /* just skip unchanged characters */
1297 mblen = wcrtomb (mb, nwc, &ps);
1298 if (mblen > 0)
1299 mb[mblen] = '\0';
1300 /* Assume the same width */
1301 strncpy (rl_line_buffer + start, mb, mblen);
1304 #endif
1306 start = next;
1309 rl_point = end;
1310 return 0;
1313 /* **************************************************************** */
1314 /* */
1315 /* Transposition */
1316 /* */
1317 /* **************************************************************** */
1319 /* Transpose the words at point. If point is at the end of the line,
1320 transpose the two words before point. */
1322 rl_transpose_words (count, key)
1323 int count, key;
1325 char *word1, *word2;
1326 int w1_beg, w1_end, w2_beg, w2_end;
1327 int orig_point = rl_point;
1329 if (!count)
1330 return 0;
1332 /* Find the two words. */
1333 rl_forward_word (count, key);
1334 w2_end = rl_point;
1335 rl_backward_word (1, key);
1336 w2_beg = rl_point;
1337 rl_backward_word (count, key);
1338 w1_beg = rl_point;
1339 rl_forward_word (1, key);
1340 w1_end = rl_point;
1342 /* Do some check to make sure that there really are two words. */
1343 if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1345 rl_ding ();
1346 rl_point = orig_point;
1347 return -1;
1350 /* Get the text of the words. */
1351 word1 = rl_copy_text (w1_beg, w1_end);
1352 word2 = rl_copy_text (w2_beg, w2_end);
1354 /* We are about to do many insertions and deletions. Remember them
1355 as one operation. */
1356 rl_begin_undo_group ();
1358 /* Do the stuff at word2 first, so that we don't have to worry
1359 about word1 moving. */
1360 rl_point = w2_beg;
1361 rl_delete_text (w2_beg, w2_end);
1362 rl_insert_text (word1);
1364 rl_point = w1_beg;
1365 rl_delete_text (w1_beg, w1_end);
1366 rl_insert_text (word2);
1368 /* This is exactly correct since the text before this point has not
1369 changed in length. */
1370 rl_point = w2_end;
1372 /* I think that does it. */
1373 rl_end_undo_group ();
1374 free (word1);
1375 free (word2);
1377 return 0;
1380 /* Transpose the characters at point. If point is at the end of the line,
1381 then transpose the characters before point. */
1383 rl_transpose_chars (count, key)
1384 int count, key;
1386 #if defined (HANDLE_MULTIBYTE)
1387 char *dummy;
1388 int i;
1389 #else
1390 char dummy[2];
1391 #endif
1392 int char_length, prev_point;
1394 if (count == 0)
1395 return 0;
1397 if (!rl_point || rl_end < 2)
1399 rl_ding ();
1400 return -1;
1403 rl_begin_undo_group ();
1405 if (rl_point == rl_end)
1407 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1408 count = 1;
1411 prev_point = rl_point;
1412 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1414 #if defined (HANDLE_MULTIBYTE)
1415 char_length = prev_point - rl_point;
1416 dummy = (char *)xmalloc (char_length + 1);
1417 for (i = 0; i < char_length; i++)
1418 dummy[i] = rl_line_buffer[rl_point + i];
1419 dummy[i] = '\0';
1420 #else
1421 dummy[0] = rl_line_buffer[rl_point];
1422 dummy[char_length = 1] = '\0';
1423 #endif
1425 rl_delete_text (rl_point, rl_point + char_length);
1427 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1429 _rl_fix_point (0);
1430 rl_insert_text (dummy);
1431 rl_end_undo_group ();
1433 #if defined (HANDLE_MULTIBYTE)
1434 free (dummy);
1435 #endif
1437 return 0;
1440 /* **************************************************************** */
1441 /* */
1442 /* Character Searching */
1443 /* */
1444 /* **************************************************************** */
1447 #if defined (HANDLE_MULTIBYTE)
1448 _rl_char_search_internal (count, dir, smbchar, len)
1449 int count, dir;
1450 char *smbchar;
1451 int len;
1452 #else
1453 _rl_char_search_internal (count, dir, schar)
1454 int count, dir, schar;
1455 #endif
1457 int pos, inc;
1458 #if defined (HANDLE_MULTIBYTE)
1459 int prepos;
1460 #endif
1462 pos = rl_point;
1463 inc = (dir < 0) ? -1 : 1;
1464 while (count)
1466 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1468 rl_ding ();
1469 return -1;
1472 #if defined (HANDLE_MULTIBYTE)
1473 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1474 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1475 #else
1476 pos += inc;
1477 #endif
1480 #if defined (HANDLE_MULTIBYTE)
1481 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1482 #else
1483 if (rl_line_buffer[pos] == schar)
1484 #endif
1486 count--;
1487 if (dir < 0)
1488 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1489 : pos;
1490 else
1491 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1492 : pos;
1493 break;
1495 #if defined (HANDLE_MULTIBYTE)
1496 prepos = pos;
1497 #endif
1499 #if defined (HANDLE_MULTIBYTE)
1500 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1501 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1502 #else
1503 while ((dir < 0) ? pos-- : ++pos < rl_end);
1504 #endif
1506 return (0);
1509 /* Search COUNT times for a character read from the current input stream.
1510 FDIR is the direction to search if COUNT is non-negative; otherwise
1511 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1512 that there are two separate versions of this function. */
1513 #if defined (HANDLE_MULTIBYTE)
1514 static int
1515 _rl_char_search (count, fdir, bdir)
1516 int count, fdir, bdir;
1518 char mbchar[MB_LEN_MAX];
1519 int mb_len;
1521 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1523 if (count < 0)
1524 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1525 else
1526 return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1528 #else /* !HANDLE_MULTIBYTE */
1529 static int
1530 _rl_char_search (count, fdir, bdir)
1531 int count, fdir, bdir;
1533 int c;
1535 RL_SETSTATE(RL_STATE_MOREINPUT);
1536 c = rl_read_key ();
1537 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1539 if (count < 0)
1540 return (_rl_char_search_internal (-count, bdir, c));
1541 else
1542 return (_rl_char_search_internal (count, fdir, c));
1544 #endif /* !HANDLE_MULTIBYTE */
1546 #if defined (READLINE_CALLBACKS)
1547 static int
1548 _rl_char_search_callback (data)
1549 _rl_callback_generic_arg *data;
1551 _rl_callback_func = 0;
1552 _rl_want_redisplay = 1;
1554 return (_rl_char_search (data->count, data->i1, data->i2));
1556 #endif
1559 rl_char_search (count, key)
1560 int count, key;
1562 #if defined (READLINE_CALLBACKS)
1563 if (RL_ISSTATE (RL_STATE_CALLBACK))
1565 _rl_callback_data = _rl_callback_data_alloc (count);
1566 _rl_callback_data->i1 = FFIND;
1567 _rl_callback_data->i2 = BFIND;
1568 _rl_callback_func = _rl_char_search_callback;
1569 return (0);
1571 #endif
1573 return (_rl_char_search (count, FFIND, BFIND));
1577 rl_backward_char_search (count, key)
1578 int count, key;
1580 #if defined (READLINE_CALLBACKS)
1581 if (RL_ISSTATE (RL_STATE_CALLBACK))
1583 _rl_callback_data = _rl_callback_data_alloc (count);
1584 _rl_callback_data->i1 = BFIND;
1585 _rl_callback_data->i2 = FFIND;
1586 _rl_callback_func = _rl_char_search_callback;
1587 return (0);
1589 #endif
1591 return (_rl_char_search (count, BFIND, FFIND));
1594 /* **************************************************************** */
1595 /* */
1596 /* The Mark and the Region. */
1597 /* */
1598 /* **************************************************************** */
1600 /* Set the mark at POSITION. */
1602 _rl_set_mark_at_pos (position)
1603 int position;
1605 if (position > rl_end)
1606 return -1;
1608 rl_mark = position;
1609 return 0;
1612 /* A bindable command to set the mark. */
1614 rl_set_mark (count, key)
1615 int count, key;
1617 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1620 /* Exchange the position of mark and point. */
1622 rl_exchange_point_and_mark (count, key)
1623 int count, key;
1625 if (rl_mark > rl_end)
1626 rl_mark = -1;
1628 if (rl_mark == -1)
1630 rl_ding ();
1631 return -1;
1633 else
1634 SWAP (rl_point, rl_mark);
1636 return 0;