]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/readline/text.c
d917e99b9bd63c659da105ed7ceac6d5becc7b32
[thirdparty/bash.git] / lib / readline / text.c
1 /* text.c -- text handling commands for readline. */
2
3 /* Copyright (C) 1987-2004 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
7
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.
12
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.
17
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
23
24 #if defined (HAVE_CONFIG_H)
25 # include <config.h>
26 #endif
27
28 #if defined (HAVE_UNISTD_H)
29 # include <unistd.h>
30 #endif /* HAVE_UNISTD_H */
31
32 #if defined (HAVE_STDLIB_H)
33 # include <stdlib.h>
34 #else
35 # include "ansi_stdlib.h"
36 #endif /* HAVE_STDLIB_H */
37
38 #if defined (HAVE_LOCALE_H)
39 # include <locale.h>
40 #endif
41
42 #include <stdio.h>
43
44 /* System-specific feature definitions and include files. */
45 #include "rldefs.h"
46 #include "rlmbutil.h"
47
48 #if defined (__EMX__)
49 # define INCL_DOSPROCESS
50 # include <os2.h>
51 #endif /* __EMX__ */
52
53 /* Some standard library routines. */
54 #include "readline.h"
55 #include "history.h"
56
57 #include "rlprivate.h"
58 #include "rlshell.h"
59 #include "xmalloc.h"
60
61 /* Forward declarations. */
62 static int rl_change_case PARAMS((int, int));
63 static int _rl_char_search PARAMS((int, int, int));
64
65 /* **************************************************************** */
66 /* */
67 /* Insert and Delete */
68 /* */
69 /* **************************************************************** */
70
71 /* Insert a string of text into the line at point. This is the only
72 way that you should do insertion. _rl_insert_char () calls this
73 function. Returns the number of characters inserted. */
74 int
75 rl_insert_text (string)
76 const char *string;
77 {
78 register int i, l;
79
80 l = (string && *string) ? strlen (string) : 0;
81 if (l == 0)
82 return 0;
83
84 if (rl_end + l >= rl_line_buffer_len)
85 rl_extend_line_buffer (rl_end + l);
86
87 for (i = rl_end; i >= rl_point; i--)
88 rl_line_buffer[i + l] = rl_line_buffer[i];
89 strncpy (rl_line_buffer + rl_point, string, l);
90
91 /* Remember how to undo this if we aren't undoing something. */
92 if (_rl_doing_an_undo == 0)
93 {
94 /* If possible and desirable, concatenate the undos. */
95 if ((l == 1) &&
96 rl_undo_list &&
97 (rl_undo_list->what == UNDO_INSERT) &&
98 (rl_undo_list->end == rl_point) &&
99 (rl_undo_list->end - rl_undo_list->start < 20))
100 rl_undo_list->end++;
101 else
102 rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
103 }
104 rl_point += l;
105 rl_end += l;
106 rl_line_buffer[rl_end] = '\0';
107 return l;
108 }
109
110 /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
111 Returns the number of characters deleted. */
112 int
113 rl_delete_text (from, to)
114 int from, to;
115 {
116 register char *text;
117 register int diff, i;
118
119 /* Fix it if the caller is confused. */
120 if (from > to)
121 SWAP (from, to);
122
123 /* fix boundaries */
124 if (to > rl_end)
125 {
126 to = rl_end;
127 if (from > to)
128 from = to;
129 }
130 if (from < 0)
131 from = 0;
132
133 text = rl_copy_text (from, to);
134
135 /* Some versions of strncpy() can't handle overlapping arguments. */
136 diff = to - from;
137 for (i = from; i < rl_end - diff; i++)
138 rl_line_buffer[i] = rl_line_buffer[i + diff];
139
140 /* Remember how to undo this delete. */
141 if (_rl_doing_an_undo == 0)
142 rl_add_undo (UNDO_DELETE, from, to, text);
143 else
144 free (text);
145
146 rl_end -= diff;
147 rl_line_buffer[rl_end] = '\0';
148 return (diff);
149 }
150
151 /* Fix up point so that it is within the line boundaries after killing
152 text. If FIX_MARK_TOO is non-zero, the mark is forced within line
153 boundaries also. */
154
155 #define _RL_FIX_POINT(x) \
156 do { \
157 if (x > rl_end) \
158 x = rl_end; \
159 else if (x < 0) \
160 x = 0; \
161 } while (0)
162
163 void
164 _rl_fix_point (fix_mark_too)
165 int fix_mark_too;
166 {
167 _RL_FIX_POINT (rl_point);
168 if (fix_mark_too)
169 _RL_FIX_POINT (rl_mark);
170 }
171 #undef _RL_FIX_POINT
172
173 /* Replace the contents of the line buffer between START and END with
174 TEXT. The operation is undoable. To replace the entire line in an
175 undoable mode, use _rl_replace_text(text, 0, rl_end); */
176 int
177 _rl_replace_text (text, start, end)
178 const char *text;
179 int start, end;
180 {
181 int n;
182
183 rl_begin_undo_group ();
184 rl_delete_text (start, end + 1);
185 rl_point = start;
186 n = rl_insert_text (text);
187 rl_end_undo_group ();
188
189 return n;
190 }
191
192 /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
193 non-zero, we free the current undo list. */
194 void
195 rl_replace_line (text, clear_undo)
196 const char *text;
197 int clear_undo;
198 {
199 int len;
200
201 len = strlen (text);
202 if (len >= rl_line_buffer_len)
203 rl_extend_line_buffer (len);
204 strcpy (rl_line_buffer, text);
205 rl_end = len;
206
207 if (clear_undo)
208 rl_free_undo_list ();
209
210 _rl_fix_point (1);
211 }
212
213 /* **************************************************************** */
214 /* */
215 /* Readline character functions */
216 /* */
217 /* **************************************************************** */
218
219 /* This is not a gap editor, just a stupid line input routine. No hair
220 is involved in writing any of the functions, and none should be. */
221
222 /* Note that:
223
224 rl_end is the place in the string that we would place '\0';
225 i.e., it is always safe to place '\0' there.
226
227 rl_point is the place in the string where the cursor is. Sometimes
228 this is the same as rl_end.
229
230 Any command that is called interactively receives two arguments.
231 The first is a count: the numeric arg pased to this command.
232 The second is the key which invoked this command.
233 */
234
235 /* **************************************************************** */
236 /* */
237 /* Movement Commands */
238 /* */
239 /* **************************************************************** */
240
241 /* Note that if you `optimize' the display for these functions, you cannot
242 use said functions in other functions which do not do optimizing display.
243 I.e., you will have to update the data base for rl_redisplay, and you
244 might as well let rl_redisplay do that job. */
245
246 /* Move forward COUNT bytes. */
247 int
248 rl_forward_byte (count, key)
249 int count, key;
250 {
251 if (count < 0)
252 return (rl_backward_byte (-count, key));
253
254 if (count > 0)
255 {
256 int end = rl_point + count;
257 #if defined (VI_MODE)
258 int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
259 #else
260 int lend = rl_end;
261 #endif
262
263 if (end > lend)
264 {
265 rl_point = lend;
266 rl_ding ();
267 }
268 else
269 rl_point = end;
270 }
271
272 if (rl_end < 0)
273 rl_end = 0;
274
275 return 0;
276 }
277
278 #if defined (HANDLE_MULTIBYTE)
279 /* Move forward COUNT characters. */
280 int
281 rl_forward_char (count, key)
282 int count, key;
283 {
284 int point;
285
286 if (MB_CUR_MAX == 1 || rl_byte_oriented)
287 return (rl_forward_byte (count, key));
288
289 if (count < 0)
290 return (rl_backward_char (-count, key));
291
292 if (count > 0)
293 {
294 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
295
296 #if defined (VI_MODE)
297 if (rl_end <= point && rl_editing_mode == vi_mode)
298 point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
299 #endif
300
301 if (rl_point == point)
302 rl_ding ();
303
304 rl_point = point;
305
306 if (rl_end < 0)
307 rl_end = 0;
308 }
309
310 return 0;
311 }
312 #else /* !HANDLE_MULTIBYTE */
313 int
314 rl_forward_char (count, key)
315 int count, key;
316 {
317 return (rl_forward_byte (count, key));
318 }
319 #endif /* !HANDLE_MULTIBYTE */
320
321 /* Backwards compatibility. */
322 int
323 rl_forward (count, key)
324 int count, key;
325 {
326 return (rl_forward_char (count, key));
327 }
328
329 /* Move backward COUNT bytes. */
330 int
331 rl_backward_byte (count, key)
332 int count, key;
333 {
334 if (count < 0)
335 return (rl_forward_byte (-count, key));
336
337 if (count > 0)
338 {
339 if (rl_point < count)
340 {
341 rl_point = 0;
342 rl_ding ();
343 }
344 else
345 rl_point -= count;
346 }
347
348 if (rl_point < 0)
349 rl_point = 0;
350
351 return 0;
352 }
353
354 #if defined (HANDLE_MULTIBYTE)
355 /* Move backward COUNT characters. */
356 int
357 rl_backward_char (count, key)
358 int count, key;
359 {
360 int point;
361
362 if (MB_CUR_MAX == 1 || rl_byte_oriented)
363 return (rl_backward_byte (count, key));
364
365 if (count < 0)
366 return (rl_forward_char (-count, key));
367
368 if (count > 0)
369 {
370 point = rl_point;
371
372 while (count > 0 && point > 0)
373 {
374 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
375 count--;
376 }
377 if (count > 0)
378 {
379 rl_point = 0;
380 rl_ding ();
381 }
382 else
383 rl_point = point;
384 }
385
386 return 0;
387 }
388 #else
389 int
390 rl_backward_char (count, key)
391 int count, key;
392 {
393 return (rl_backward_byte (count, key));
394 }
395 #endif
396
397 /* Backwards compatibility. */
398 int
399 rl_backward (count, key)
400 int count, key;
401 {
402 return (rl_backward_char (count, key));
403 }
404
405 /* Move to the beginning of the line. */
406 int
407 rl_beg_of_line (count, key)
408 int count, key;
409 {
410 rl_point = 0;
411 return 0;
412 }
413
414 /* Move to the end of the line. */
415 int
416 rl_end_of_line (count, key)
417 int count, key;
418 {
419 rl_point = rl_end;
420 return 0;
421 }
422
423 /* XXX - these might need changes for multibyte characters */
424 /* Move forward a word. We do what Emacs does. */
425 int
426 rl_forward_word (count, key)
427 int count, key;
428 {
429 int c;
430
431 if (count < 0)
432 return (rl_backward_word (-count, key));
433
434 while (count)
435 {
436 if (rl_point == rl_end)
437 return 0;
438
439 /* If we are not in a word, move forward until we are in one.
440 Then, move forward until we hit a non-alphabetic character. */
441 c = rl_line_buffer[rl_point];
442 if (rl_alphabetic (c) == 0)
443 {
444 while (++rl_point < rl_end)
445 {
446 c = rl_line_buffer[rl_point];
447 if (rl_alphabetic (c))
448 break;
449 }
450 }
451
452 if (rl_point == rl_end)
453 return 0;
454
455 while (++rl_point < rl_end)
456 {
457 c = rl_line_buffer[rl_point];
458 if (rl_alphabetic (c) == 0)
459 break;
460 }
461 --count;
462 }
463
464 return 0;
465 }
466
467 /* Move backward a word. We do what Emacs does. */
468 int
469 rl_backward_word (count, key)
470 int count, key;
471 {
472 int c;
473
474 if (count < 0)
475 return (rl_forward_word (-count, key));
476
477 while (count)
478 {
479 if (!rl_point)
480 return 0;
481
482 /* Like rl_forward_word (), except that we look at the characters
483 just before point. */
484
485 c = rl_line_buffer[rl_point - 1];
486 if (rl_alphabetic (c) == 0)
487 {
488 while (--rl_point)
489 {
490 c = rl_line_buffer[rl_point - 1];
491 if (rl_alphabetic (c))
492 break;
493 }
494 }
495
496 while (rl_point)
497 {
498 c = rl_line_buffer[rl_point - 1];
499 if (rl_alphabetic (c) == 0)
500 break;
501 else
502 --rl_point;
503 }
504
505 --count;
506 }
507
508 return 0;
509 }
510
511 /* Clear the current line. Numeric argument to C-l does this. */
512 int
513 rl_refresh_line (ignore1, ignore2)
514 int ignore1, ignore2;
515 {
516 int curr_line;
517
518 curr_line = _rl_current_display_line ();
519
520 _rl_move_vert (curr_line);
521 _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
522
523 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
524
525 rl_forced_update_display ();
526 rl_display_fixed = 1;
527
528 return 0;
529 }
530
531 /* C-l typed to a line without quoting clears the screen, and then reprints
532 the prompt and the current input line. Given a numeric arg, redraw only
533 the current line. */
534 int
535 rl_clear_screen (count, key)
536 int count, key;
537 {
538 if (rl_explicit_arg)
539 {
540 rl_refresh_line (count, key);
541 return 0;
542 }
543
544 _rl_clear_screen (); /* calls termcap function to clear screen */
545 rl_forced_update_display ();
546 rl_display_fixed = 1;
547
548 return 0;
549 }
550
551 int
552 rl_arrow_keys (count, c)
553 int count, c;
554 {
555 int ch;
556
557 RL_SETSTATE(RL_STATE_MOREINPUT);
558 ch = rl_read_key ();
559 RL_UNSETSTATE(RL_STATE_MOREINPUT);
560
561 switch (_rl_to_upper (ch))
562 {
563 case 'A':
564 rl_get_previous_history (count, ch);
565 break;
566
567 case 'B':
568 rl_get_next_history (count, ch);
569 break;
570
571 case 'C':
572 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
573 rl_forward_char (count, ch);
574 else
575 rl_forward_byte (count, ch);
576 break;
577
578 case 'D':
579 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
580 rl_backward_char (count, ch);
581 else
582 rl_backward_byte (count, ch);
583 break;
584
585 default:
586 rl_ding ();
587 }
588
589 return 0;
590 }
591
592 /* **************************************************************** */
593 /* */
594 /* Text commands */
595 /* */
596 /* **************************************************************** */
597
598 #ifdef HANDLE_MULTIBYTE
599 static char pending_bytes[MB_LEN_MAX];
600 static int pending_bytes_length = 0;
601 static mbstate_t ps = {0};
602 #endif
603
604 /* Insert the character C at the current location, moving point forward.
605 If C introduces a multibyte sequence, we read the whole sequence and
606 then insert the multibyte char into the line buffer. */
607 int
608 _rl_insert_char (count, c)
609 int count, c;
610 {
611 register int i;
612 char *string;
613 #ifdef HANDLE_MULTIBYTE
614 int string_size;
615 char incoming[MB_LEN_MAX + 1];
616 int incoming_length = 0;
617 mbstate_t ps_back;
618 static int stored_count = 0;
619 #endif
620
621 if (count <= 0)
622 return 0;
623
624 #if defined (HANDLE_MULTIBYTE)
625 if (MB_CUR_MAX == 1 || rl_byte_oriented)
626 {
627 incoming[0] = c;
628 incoming[1] = '\0';
629 incoming_length = 1;
630 }
631 else
632 {
633 wchar_t wc;
634 size_t ret;
635
636 if (stored_count <= 0)
637 stored_count = count;
638 else
639 count = stored_count;
640
641 ps_back = ps;
642 pending_bytes[pending_bytes_length++] = c;
643 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
644
645 if (ret == (size_t)-2)
646 {
647 /* Bytes too short to compose character, try to wait for next byte.
648 Restore the state of the byte sequence, because in this case the
649 effect of mbstate is undefined. */
650 ps = ps_back;
651 return 1;
652 }
653 else if (ret == (size_t)-1)
654 {
655 /* Invalid byte sequence for the current locale. Treat first byte
656 as a single character. */
657 incoming[0] = pending_bytes[0];
658 incoming[1] = '\0';
659 incoming_length = 1;
660 pending_bytes_length--;
661 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
662 /* Clear the state of the byte sequence, because in this case the
663 effect of mbstate is undefined. */
664 memset (&ps, 0, sizeof (mbstate_t));
665 }
666 else if (ret == (size_t)0)
667 {
668 incoming[0] = '\0';
669 incoming_length = 0;
670 pending_bytes_length--;
671 /* Clear the state of the byte sequence, because in this case the
672 effect of mbstate is undefined. */
673 memset (&ps, 0, sizeof (mbstate_t));
674 }
675 else
676 {
677 /* We successfully read a single multibyte character. */
678 memcpy (incoming, pending_bytes, pending_bytes_length);
679 incoming[pending_bytes_length] = '\0';
680 incoming_length = pending_bytes_length;
681 pending_bytes_length = 0;
682 }
683 }
684 #endif /* HANDLE_MULTIBYTE */
685
686 /* If we can optimize, then do it. But don't let people crash
687 readline because of extra large arguments. */
688 if (count > 1 && count <= 1024)
689 {
690 #if defined (HANDLE_MULTIBYTE)
691 string_size = count * incoming_length;
692 string = (char *)xmalloc (1 + string_size);
693
694 i = 0;
695 while (i < string_size)
696 {
697 strncpy (string + i, incoming, incoming_length);
698 i += incoming_length;
699 }
700 incoming_length = 0;
701 stored_count = 0;
702 #else /* !HANDLE_MULTIBYTE */
703 string = (char *)xmalloc (1 + count);
704
705 for (i = 0; i < count; i++)
706 string[i] = c;
707 #endif /* !HANDLE_MULTIBYTE */
708
709 string[i] = '\0';
710 rl_insert_text (string);
711 free (string);
712
713 return 0;
714 }
715
716 if (count > 1024)
717 {
718 int decreaser;
719 #if defined (HANDLE_MULTIBYTE)
720 string_size = incoming_length * 1024;
721 string = (char *)xmalloc (1 + string_size);
722
723 i = 0;
724 while (i < string_size)
725 {
726 strncpy (string + i, incoming, incoming_length);
727 i += incoming_length;
728 }
729
730 while (count)
731 {
732 decreaser = (count > 1024) ? 1024 : count;
733 string[decreaser*incoming_length] = '\0';
734 rl_insert_text (string);
735 count -= decreaser;
736 }
737
738 free (string);
739 incoming_length = 0;
740 stored_count = 0;
741 #else /* !HANDLE_MULTIBYTE */
742 char str[1024+1];
743
744 for (i = 0; i < 1024; i++)
745 str[i] = c;
746
747 while (count)
748 {
749 decreaser = (count > 1024 ? 1024 : count);
750 str[decreaser] = '\0';
751 rl_insert_text (str);
752 count -= decreaser;
753 }
754 #endif /* !HANDLE_MULTIBYTE */
755
756 return 0;
757 }
758
759 #if defined (HANDLE_MULTIBYTE)
760 if (MB_CUR_MAX == 1 || rl_byte_oriented)
761 {
762 #endif
763 /* We are inserting a single character.
764 If there is pending input, then make a string of all of the
765 pending characters that are bound to rl_insert, and insert
766 them all. */
767 if (_rl_any_typein ())
768 _rl_insert_typein (c);
769 else
770 {
771 /* Inserting a single character. */
772 char str[2];
773
774 str[1] = '\0';
775 str[0] = c;
776 rl_insert_text (str);
777 }
778 #if defined (HANDLE_MULTIBYTE)
779 }
780 else
781 {
782 rl_insert_text (incoming);
783 stored_count = 0;
784 }
785 #endif
786
787 return 0;
788 }
789
790 /* Overwrite the character at point (or next COUNT characters) with C.
791 If C introduces a multibyte character sequence, read the entire sequence
792 before starting the overwrite loop. */
793 int
794 _rl_overwrite_char (count, c)
795 int count, c;
796 {
797 int i;
798 #if defined (HANDLE_MULTIBYTE)
799 char mbkey[MB_LEN_MAX];
800 int k;
801
802 /* Read an entire multibyte character sequence to insert COUNT times. */
803 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
804 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
805 #endif
806
807 rl_begin_undo_group ();
808
809 for (i = 0; i < count; i++)
810 {
811 #if defined (HANDLE_MULTIBYTE)
812 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
813 rl_insert_text (mbkey);
814 else
815 #endif
816 _rl_insert_char (1, c);
817
818 if (rl_point < rl_end)
819 rl_delete (1, c);
820 }
821
822 rl_end_undo_group ();
823
824 return 0;
825 }
826
827 int
828 rl_insert (count, c)
829 int count, c;
830 {
831 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
832 : _rl_overwrite_char (count, c));
833 }
834
835 /* Insert the next typed character verbatim. */
836 int
837 rl_quoted_insert (count, key)
838 int count, key;
839 {
840 int c;
841
842 #if defined (HANDLE_SIGNALS)
843 _rl_disable_tty_signals ();
844 #endif
845
846 RL_SETSTATE(RL_STATE_MOREINPUT);
847 c = rl_read_key ();
848 RL_UNSETSTATE(RL_STATE_MOREINPUT);
849
850 #if defined (HANDLE_SIGNALS)
851 _rl_restore_tty_signals ();
852 #endif
853
854 return (_rl_insert_char (count, c));
855 }
856
857 /* Insert a tab character. */
858 int
859 rl_tab_insert (count, key)
860 int count, key;
861 {
862 return (_rl_insert_char (count, '\t'));
863 }
864
865 /* What to do when a NEWLINE is pressed. We accept the whole line.
866 KEY is the key that invoked this command. I guess it could have
867 meaning in the future. */
868 int
869 rl_newline (count, key)
870 int count, key;
871 {
872 rl_done = 1;
873
874 if (_rl_history_preserve_point)
875 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
876
877 RL_SETSTATE(RL_STATE_DONE);
878
879 #if defined (VI_MODE)
880 if (rl_editing_mode == vi_mode)
881 {
882 _rl_vi_done_inserting ();
883 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
884 _rl_vi_reset_last ();
885 }
886 #endif /* VI_MODE */
887
888 /* If we've been asked to erase empty lines, suppress the final update,
889 since _rl_update_final calls rl_crlf(). */
890 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
891 return 0;
892
893 if (readline_echoing_p)
894 _rl_update_final ();
895 return 0;
896 }
897
898 /* What to do for some uppercase characters, like meta characters,
899 and some characters appearing in emacs_ctlx_keymap. This function
900 is just a stub, you bind keys to it and the code in _rl_dispatch ()
901 is special cased. */
902 int
903 rl_do_lowercase_version (ignore1, ignore2)
904 int ignore1, ignore2;
905 {
906 return 0;
907 }
908
909 /* This is different from what vi does, so the code's not shared. Emacs
910 rubout in overwrite mode has one oddity: it replaces a control
911 character that's displayed as two characters (^X) with two spaces. */
912 int
913 _rl_overwrite_rubout (count, key)
914 int count, key;
915 {
916 int opoint;
917 int i, l;
918
919 if (rl_point == 0)
920 {
921 rl_ding ();
922 return 1;
923 }
924
925 opoint = rl_point;
926
927 /* L == number of spaces to insert */
928 for (i = l = 0; i < count; i++)
929 {
930 rl_backward_char (1, key);
931 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
932 }
933
934 rl_begin_undo_group ();
935
936 if (count > 1 || rl_explicit_arg)
937 rl_kill_text (opoint, rl_point);
938 else
939 rl_delete_text (opoint, rl_point);
940
941 /* Emacs puts point at the beginning of the sequence of spaces. */
942 if (rl_point < rl_end)
943 {
944 opoint = rl_point;
945 _rl_insert_char (l, ' ');
946 rl_point = opoint;
947 }
948
949 rl_end_undo_group ();
950
951 return 0;
952 }
953
954 /* Rubout the character behind point. */
955 int
956 rl_rubout (count, key)
957 int count, key;
958 {
959 if (count < 0)
960 return (rl_delete (-count, key));
961
962 if (!rl_point)
963 {
964 rl_ding ();
965 return -1;
966 }
967
968 if (rl_insert_mode == RL_IM_OVERWRITE)
969 return (_rl_overwrite_rubout (count, key));
970
971 return (_rl_rubout_char (count, key));
972 }
973
974 int
975 _rl_rubout_char (count, key)
976 int count, key;
977 {
978 int orig_point;
979 unsigned char c;
980
981 /* Duplicated code because this is called from other parts of the library. */
982 if (count < 0)
983 return (rl_delete (-count, key));
984
985 if (rl_point == 0)
986 {
987 rl_ding ();
988 return -1;
989 }
990
991 if (count > 1 || rl_explicit_arg)
992 {
993 orig_point = rl_point;
994 #if defined (HANDLE_MULTIBYTE)
995 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
996 rl_backward_char (count, key);
997 else
998 #endif
999 rl_backward_byte (count, key);
1000 rl_kill_text (orig_point, rl_point);
1001 }
1002 else
1003 {
1004 #if defined (HANDLE_MULTIBYTE)
1005 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1006 {
1007 #endif
1008 c = rl_line_buffer[--rl_point];
1009 rl_delete_text (rl_point, rl_point + 1);
1010 #if defined (HANDLE_MULTIBYTE)
1011 }
1012 else
1013 {
1014 int orig_point;
1015
1016 orig_point = rl_point;
1017 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1018 c = rl_line_buffer[rl_point];
1019 rl_delete_text (rl_point, orig_point);
1020 }
1021 #endif /* HANDLE_MULTIBYTE */
1022
1023 /* I don't think that the hack for end of line is needed for
1024 multibyte chars. */
1025 #if defined (HANDLE_MULTIBYTE)
1026 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1027 #endif
1028 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
1029 {
1030 int l;
1031 l = rl_character_len (c, rl_point);
1032 _rl_erase_at_end_of_line (l);
1033 }
1034 }
1035
1036 return 0;
1037 }
1038
1039 /* Delete the character under the cursor. Given a numeric argument,
1040 kill that many characters instead. */
1041 int
1042 rl_delete (count, key)
1043 int count, key;
1044 {
1045 int r;
1046
1047 if (count < 0)
1048 return (_rl_rubout_char (-count, key));
1049
1050 if (rl_point == rl_end)
1051 {
1052 rl_ding ();
1053 return -1;
1054 }
1055
1056 if (count > 1 || rl_explicit_arg)
1057 {
1058 int orig_point = rl_point;
1059 #if defined (HANDLE_MULTIBYTE)
1060 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1061 rl_forward_char (count, key);
1062 else
1063 #endif
1064 rl_forward_byte (count, key);
1065
1066 r = rl_kill_text (orig_point, rl_point);
1067 rl_point = orig_point;
1068 return r;
1069 }
1070 else
1071 {
1072 int new_point;
1073 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1074 new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1075 else
1076 new_point = rl_point + 1;
1077
1078 return (rl_delete_text (rl_point, new_point));
1079 }
1080 }
1081
1082 /* Delete the character under the cursor, unless the insertion
1083 point is at the end of the line, in which case the character
1084 behind the cursor is deleted. COUNT is obeyed and may be used
1085 to delete forward or backward that many characters. */
1086 int
1087 rl_rubout_or_delete (count, key)
1088 int count, key;
1089 {
1090 if (rl_end != 0 && rl_point == rl_end)
1091 return (_rl_rubout_char (count, key));
1092 else
1093 return (rl_delete (count, key));
1094 }
1095
1096 /* Delete all spaces and tabs around point. */
1097 int
1098 rl_delete_horizontal_space (count, ignore)
1099 int count, ignore;
1100 {
1101 int start = rl_point;
1102
1103 while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1104 rl_point--;
1105
1106 start = rl_point;
1107
1108 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1109 rl_point++;
1110
1111 if (start != rl_point)
1112 {
1113 rl_delete_text (start, rl_point);
1114 rl_point = start;
1115 }
1116 return 0;
1117 }
1118
1119 /* Like the tcsh editing function delete-char-or-list. The eof character
1120 is caught before this is invoked, so this really does the same thing as
1121 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1122 int
1123 rl_delete_or_show_completions (count, key)
1124 int count, key;
1125 {
1126 if (rl_end != 0 && rl_point == rl_end)
1127 return (rl_possible_completions (count, key));
1128 else
1129 return (rl_delete (count, key));
1130 }
1131
1132 #ifndef RL_COMMENT_BEGIN_DEFAULT
1133 #define RL_COMMENT_BEGIN_DEFAULT "#"
1134 #endif
1135
1136 /* Turn the current line into a comment in shell history.
1137 A K*rn shell style function. */
1138 int
1139 rl_insert_comment (count, key)
1140 int count, key;
1141 {
1142 char *rl_comment_text;
1143 int rl_comment_len;
1144
1145 rl_beg_of_line (1, key);
1146 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1147
1148 if (rl_explicit_arg == 0)
1149 rl_insert_text (rl_comment_text);
1150 else
1151 {
1152 rl_comment_len = strlen (rl_comment_text);
1153 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1154 rl_delete_text (rl_point, rl_point + rl_comment_len);
1155 else
1156 rl_insert_text (rl_comment_text);
1157 }
1158
1159 (*rl_redisplay_function) ();
1160 rl_newline (1, '\n');
1161
1162 return (0);
1163 }
1164
1165 /* **************************************************************** */
1166 /* */
1167 /* Changing Case */
1168 /* */
1169 /* **************************************************************** */
1170
1171 /* The three kinds of things that we know how to do. */
1172 #define UpCase 1
1173 #define DownCase 2
1174 #define CapCase 3
1175
1176 /* Uppercase the word at point. */
1177 int
1178 rl_upcase_word (count, key)
1179 int count, key;
1180 {
1181 return (rl_change_case (count, UpCase));
1182 }
1183
1184 /* Lowercase the word at point. */
1185 int
1186 rl_downcase_word (count, key)
1187 int count, key;
1188 {
1189 return (rl_change_case (count, DownCase));
1190 }
1191
1192 /* Upcase the first letter, downcase the rest. */
1193 int
1194 rl_capitalize_word (count, key)
1195 int count, key;
1196 {
1197 return (rl_change_case (count, CapCase));
1198 }
1199
1200 /* The meaty function.
1201 Change the case of COUNT words, performing OP on them.
1202 OP is one of UpCase, DownCase, or CapCase.
1203 If a negative argument is given, leave point where it started,
1204 otherwise, leave it where it moves to. */
1205 static int
1206 rl_change_case (count, op)
1207 int count, op;
1208 {
1209 register int start, end;
1210 int inword, c;
1211
1212 start = rl_point;
1213 rl_forward_word (count, 0);
1214 end = rl_point;
1215
1216 if (count < 0)
1217 SWAP (start, end);
1218
1219 /* We are going to modify some text, so let's prepare to undo it. */
1220 rl_modifying (start, end);
1221
1222 for (inword = 0; start < end; start++)
1223 {
1224 c = rl_line_buffer[start];
1225 switch (op)
1226 {
1227 case UpCase:
1228 rl_line_buffer[start] = _rl_to_upper (c);
1229 break;
1230
1231 case DownCase:
1232 rl_line_buffer[start] = _rl_to_lower (c);
1233 break;
1234
1235 case CapCase:
1236 rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
1237 inword = rl_alphabetic (rl_line_buffer[start]);
1238 break;
1239
1240 default:
1241 rl_ding ();
1242 return -1;
1243 }
1244 }
1245 rl_point = end;
1246 return 0;
1247 }
1248
1249 /* **************************************************************** */
1250 /* */
1251 /* Transposition */
1252 /* */
1253 /* **************************************************************** */
1254
1255 /* Transpose the words at point. If point is at the end of the line,
1256 transpose the two words before point. */
1257 int
1258 rl_transpose_words (count, key)
1259 int count, key;
1260 {
1261 char *word1, *word2;
1262 int w1_beg, w1_end, w2_beg, w2_end;
1263 int orig_point = rl_point;
1264
1265 if (!count)
1266 return 0;
1267
1268 /* Find the two words. */
1269 rl_forward_word (count, key);
1270 w2_end = rl_point;
1271 rl_backward_word (1, key);
1272 w2_beg = rl_point;
1273 rl_backward_word (count, key);
1274 w1_beg = rl_point;
1275 rl_forward_word (1, key);
1276 w1_end = rl_point;
1277
1278 /* Do some check to make sure that there really are two words. */
1279 if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1280 {
1281 rl_ding ();
1282 rl_point = orig_point;
1283 return -1;
1284 }
1285
1286 /* Get the text of the words. */
1287 word1 = rl_copy_text (w1_beg, w1_end);
1288 word2 = rl_copy_text (w2_beg, w2_end);
1289
1290 /* We are about to do many insertions and deletions. Remember them
1291 as one operation. */
1292 rl_begin_undo_group ();
1293
1294 /* Do the stuff at word2 first, so that we don't have to worry
1295 about word1 moving. */
1296 rl_point = w2_beg;
1297 rl_delete_text (w2_beg, w2_end);
1298 rl_insert_text (word1);
1299
1300 rl_point = w1_beg;
1301 rl_delete_text (w1_beg, w1_end);
1302 rl_insert_text (word2);
1303
1304 /* This is exactly correct since the text before this point has not
1305 changed in length. */
1306 rl_point = w2_end;
1307
1308 /* I think that does it. */
1309 rl_end_undo_group ();
1310 free (word1);
1311 free (word2);
1312
1313 return 0;
1314 }
1315
1316 /* Transpose the characters at point. If point is at the end of the line,
1317 then transpose the characters before point. */
1318 int
1319 rl_transpose_chars (count, key)
1320 int count, key;
1321 {
1322 #if defined (HANDLE_MULTIBYTE)
1323 char *dummy;
1324 int i, prev_point;
1325 #else
1326 char dummy[2];
1327 #endif
1328 int char_length;
1329
1330 if (count == 0)
1331 return 0;
1332
1333 if (!rl_point || rl_end < 2)
1334 {
1335 rl_ding ();
1336 return -1;
1337 }
1338
1339 rl_begin_undo_group ();
1340
1341 if (rl_point == rl_end)
1342 {
1343 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1344 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1345 else
1346 --rl_point;
1347 count = 1;
1348 }
1349
1350 #if defined (HANDLE_MULTIBYTE)
1351 prev_point = rl_point;
1352 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1353 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1354 else
1355 #endif
1356 rl_point--;
1357
1358 #if defined (HANDLE_MULTIBYTE)
1359 char_length = prev_point - rl_point;
1360 dummy = (char *)xmalloc (char_length + 1);
1361 for (i = 0; i < char_length; i++)
1362 dummy[i] = rl_line_buffer[rl_point + i];
1363 dummy[i] = '\0';
1364 #else
1365 dummy[0] = rl_line_buffer[rl_point];
1366 dummy[char_length = 1] = '\0';
1367 #endif
1368
1369 rl_delete_text (rl_point, rl_point + char_length);
1370
1371 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1372
1373 _rl_fix_point (0);
1374 rl_insert_text (dummy);
1375 rl_end_undo_group ();
1376
1377 #if defined (HANDLE_MULTIBYTE)
1378 free (dummy);
1379 #endif
1380
1381 return 0;
1382 }
1383
1384 /* **************************************************************** */
1385 /* */
1386 /* Character Searching */
1387 /* */
1388 /* **************************************************************** */
1389
1390 int
1391 #if defined (HANDLE_MULTIBYTE)
1392 _rl_char_search_internal (count, dir, smbchar, len)
1393 int count, dir;
1394 char *smbchar;
1395 int len;
1396 #else
1397 _rl_char_search_internal (count, dir, schar)
1398 int count, dir, schar;
1399 #endif
1400 {
1401 int pos, inc;
1402 #if defined (HANDLE_MULTIBYTE)
1403 int prepos;
1404 #endif
1405
1406 pos = rl_point;
1407 inc = (dir < 0) ? -1 : 1;
1408 while (count)
1409 {
1410 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1411 {
1412 rl_ding ();
1413 return -1;
1414 }
1415
1416 #if defined (HANDLE_MULTIBYTE)
1417 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1418 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1419 #else
1420 pos += inc;
1421 #endif
1422 do
1423 {
1424 #if defined (HANDLE_MULTIBYTE)
1425 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1426 #else
1427 if (rl_line_buffer[pos] == schar)
1428 #endif
1429 {
1430 count--;
1431 if (dir < 0)
1432 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1433 : pos;
1434 else
1435 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1436 : pos;
1437 break;
1438 }
1439 #if defined (HANDLE_MULTIBYTE)
1440 prepos = pos;
1441 #endif
1442 }
1443 #if defined (HANDLE_MULTIBYTE)
1444 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1445 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1446 #else
1447 while ((dir < 0) ? pos-- : ++pos < rl_end);
1448 #endif
1449 }
1450 return (0);
1451 }
1452
1453 /* Search COUNT times for a character read from the current input stream.
1454 FDIR is the direction to search if COUNT is non-negative; otherwise
1455 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1456 that there are two separate versions of this function. */
1457 #if defined (HANDLE_MULTIBYTE)
1458 static int
1459 _rl_char_search (count, fdir, bdir)
1460 int count, fdir, bdir;
1461 {
1462 char mbchar[MB_LEN_MAX];
1463 int mb_len;
1464
1465 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1466
1467 if (count < 0)
1468 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1469 else
1470 return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1471 }
1472 #else /* !HANDLE_MULTIBYTE */
1473 static int
1474 _rl_char_search (count, fdir, bdir)
1475 int count, fdir, bdir;
1476 {
1477 int c;
1478
1479 RL_SETSTATE(RL_STATE_MOREINPUT);
1480 c = rl_read_key ();
1481 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1482
1483 if (count < 0)
1484 return (_rl_char_search_internal (-count, bdir, c));
1485 else
1486 return (_rl_char_search_internal (count, fdir, c));
1487 }
1488 #endif /* !HANDLE_MULTIBYTE */
1489
1490 int
1491 rl_char_search (count, key)
1492 int count, key;
1493 {
1494 return (_rl_char_search (count, FFIND, BFIND));
1495 }
1496
1497 int
1498 rl_backward_char_search (count, key)
1499 int count, key;
1500 {
1501 return (_rl_char_search (count, BFIND, FFIND));
1502 }
1503
1504 /* **************************************************************** */
1505 /* */
1506 /* The Mark and the Region. */
1507 /* */
1508 /* **************************************************************** */
1509
1510 /* Set the mark at POSITION. */
1511 int
1512 _rl_set_mark_at_pos (position)
1513 int position;
1514 {
1515 if (position > rl_end)
1516 return -1;
1517
1518 rl_mark = position;
1519 return 0;
1520 }
1521
1522 /* A bindable command to set the mark. */
1523 int
1524 rl_set_mark (count, key)
1525 int count, key;
1526 {
1527 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1528 }
1529
1530 /* Exchange the position of mark and point. */
1531 int
1532 rl_exchange_point_and_mark (count, key)
1533 int count, key;
1534 {
1535 if (rl_mark > rl_end)
1536 rl_mark = -1;
1537
1538 if (rl_mark == -1)
1539 {
1540 rl_ding ();
1541 return -1;
1542 }
1543 else
1544 SWAP (rl_point, rl_mark);
1545
1546 return 0;
1547 }