]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/readline/text.c
Bash-5.3 distribution sources and documentation
[thirdparty/bash.git] / lib / readline / text.c
1 /* text.c -- text handling commands for readline. */
2
3 /* Copyright (C) 1987-2021,2023-2024 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
7
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20 */
21
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 (int, int);
63 static int _rl_char_search (int, int, int);
64
65 #if defined (READLINE_CALLBACKS)
66 static int _rl_insert_next_callback (_rl_callback_generic_arg *);
67 static int _rl_char_search_callback (_rl_callback_generic_arg *);
68 #endif
69
70 /* The largest chunk of text that can be inserted in one call to
71 rl_insert_text. Text blocks larger than this are divided. */
72 #define TEXT_COUNT_MAX 1024
73
74 int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */
75
76 /* **************************************************************** */
77 /* */
78 /* Insert and Delete */
79 /* */
80 /* **************************************************************** */
81
82 /* Insert a string of text into the line at point. This is the only
83 way that you should do insertion. _rl_insert_char () calls this
84 function. Returns the number of characters inserted. */
85 int
86 rl_insert_text (const char *string)
87 {
88 register int i;
89 size_t l;
90
91 l = (string && *string) ? strlen (string) : 0;
92 if (l == 0)
93 return 0;
94
95 if (rl_end + l >= rl_line_buffer_len)
96 rl_extend_line_buffer (rl_end + l);
97
98 for (i = rl_end; i >= rl_point; i--)
99 rl_line_buffer[i + l] = rl_line_buffer[i];
100
101 strncpy (rl_line_buffer + rl_point, string, l);
102
103 /* Remember how to undo this if we aren't undoing something. */
104 if (_rl_doing_an_undo == 0)
105 {
106 /* If possible and desirable, concatenate the undos. */
107 if ((l == 1) &&
108 rl_undo_list &&
109 (rl_undo_list->what == UNDO_INSERT) &&
110 (rl_undo_list->end == rl_point) &&
111 (rl_undo_list->end - rl_undo_list->start < 20))
112 rl_undo_list->end++;
113 else
114 rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
115 }
116 rl_point += l;
117 rl_end += l;
118 rl_line_buffer[rl_end] = '\0';
119 return l;
120 }
121
122 /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
123 Returns the number of characters deleted. */
124 int
125 rl_delete_text (int from, int to)
126 {
127 register char *text;
128 register int diff, i;
129
130 /* Fix it if the caller is confused. */
131 if (from > to)
132 SWAP (from, to);
133
134 /* fix boundaries */
135 if (to > rl_end)
136 {
137 to = rl_end;
138 if (from > to)
139 from = to;
140 }
141 if (from < 0)
142 from = 0;
143
144 text = rl_copy_text (from, to);
145
146 /* Some versions of strncpy() can't handle overlapping arguments. */
147 diff = to - from;
148 for (i = from; i < rl_end - diff; i++)
149 rl_line_buffer[i] = rl_line_buffer[i + diff];
150
151 /* Remember how to undo this delete. */
152 if (_rl_doing_an_undo == 0)
153 rl_add_undo (UNDO_DELETE, from, to, text);
154 else
155 xfree (text);
156
157 rl_end -= diff;
158 rl_line_buffer[rl_end] = '\0';
159 _rl_fix_mark ();
160 return (diff);
161 }
162
163 /* Fix up point so that it is within the line boundaries after killing
164 text. If FIX_MARK_TOO is non-zero, the mark is forced within line
165 boundaries also. */
166
167 #define _RL_FIX_POINT(x) \
168 do { \
169 if (x > rl_end) \
170 x = rl_end; \
171 else if (x < 0) \
172 x = 0; \
173 } while (0)
174
175 void
176 _rl_fix_point (int fix_mark_too)
177 {
178 _RL_FIX_POINT (rl_point);
179 if (fix_mark_too)
180 _RL_FIX_POINT (rl_mark);
181 }
182
183 void
184 _rl_fix_mark (void)
185 {
186 _RL_FIX_POINT (rl_mark);
187 }
188 #undef _RL_FIX_POINT
189
190 /* Replace the contents of the line buffer between START and END with
191 TEXT. The operation is undoable. To replace the entire line in an
192 undoable mode, use _rl_replace_text(text, 0, rl_end); */
193 int
194 _rl_replace_text (const char *text, int start, int end)
195 {
196 int n;
197
198 n = 0;
199 rl_begin_undo_group ();
200 if (start <= end)
201 rl_delete_text (start, end + 1);
202 rl_point = start;
203 if (*text)
204 n = rl_insert_text (text);
205 rl_end_undo_group ();
206
207 return n;
208 }
209
210 /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
211 non-zero, we free the current undo list. */
212 void
213 rl_replace_line (const char *text, int clear_undo)
214 {
215 int len;
216
217 len = strlen (text);
218 if (len >= rl_line_buffer_len)
219 rl_extend_line_buffer (len);
220 strcpy (rl_line_buffer, text);
221 rl_end = len;
222
223 if (clear_undo)
224 rl_free_undo_list ();
225
226 _rl_fix_point (1);
227 }
228
229 /* **************************************************************** */
230 /* */
231 /* Readline character functions */
232 /* */
233 /* **************************************************************** */
234
235 /* This is not a gap editor, just a stupid line input routine. No hair
236 is involved in writing any of the functions, and none should be. */
237
238 /* Note that:
239
240 rl_end is the place in the string that we would place '\0';
241 i.e., it is always safe to place '\0' there.
242
243 rl_point is the place in the string where the cursor is. Sometimes
244 this is the same as rl_end.
245
246 Any command that is called interactively receives two arguments.
247 The first is a count: the numeric arg passed to this command.
248 The second is the key which invoked this command.
249 */
250
251 /* **************************************************************** */
252 /* */
253 /* Movement Commands */
254 /* */
255 /* **************************************************************** */
256
257 /* Note that if you `optimize' the display for these functions, you cannot
258 use said functions in other functions which do not do optimizing display.
259 I.e., you will have to update the data base for rl_redisplay, and you
260 might as well let rl_redisplay do that job. */
261
262 /* Move forward COUNT bytes. */
263 int
264 rl_forward_byte (int count, int key)
265 {
266 if (count < 0)
267 return (rl_backward_byte (-count, key));
268
269 if (count > 0)
270 {
271 int end, lend;
272
273 end = rl_point + count;
274 #if defined (VI_MODE)
275 lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
276 #else
277 lend = rl_end;
278 #endif
279
280 if (end > lend)
281 {
282 rl_point = lend;
283 rl_ding ();
284 }
285 else
286 rl_point = end;
287 }
288
289 if (rl_end < 0)
290 rl_end = 0;
291
292 return 0;
293 }
294
295 int
296 _rl_forward_char_internal (int count)
297 {
298 int point;
299
300 #if defined (HANDLE_MULTIBYTE)
301 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
302
303 #if defined (VI_MODE)
304 if (point >= rl_end && VI_COMMAND_MODE())
305 point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
306 #endif
307
308 if (rl_end < 0)
309 rl_end = 0;
310 #else
311 point = rl_point + count;
312 #endif
313
314 if (point > rl_end)
315 point = rl_end;
316 return (point);
317 }
318
319 int
320 _rl_backward_char_internal (int count)
321 {
322 int point;
323
324 point = rl_point;
325 #if defined (HANDLE_MULTIBYTE)
326 if (count > 0)
327 {
328 while (count > 0 && point > 0)
329 {
330 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
331 count--;
332 }
333 if (count > 0)
334 return 0; /* XXX - rl_ding() here? */
335 }
336 #else
337 if (count > 0)
338 point -= count;
339 #endif
340
341 if (point < 0)
342 point = 0;
343 return (point);
344 }
345
346 #if defined (HANDLE_MULTIBYTE)
347 /* Move forward COUNT characters. */
348 int
349 rl_forward_char (int count, int key)
350 {
351 int point;
352
353 if (MB_CUR_MAX == 1 || rl_byte_oriented)
354 return (rl_forward_byte (count, key));
355
356 if (count < 0)
357 return (rl_backward_char (-count, key));
358
359 if (count > 0)
360 {
361 if (rl_point == rl_end && EMACS_MODE())
362 {
363 rl_ding ();
364 return 0;
365 }
366
367 point = _rl_forward_char_internal (count);
368
369 if (rl_point == point)
370 rl_ding ();
371
372 rl_point = point;
373 }
374
375 return 0;
376 }
377 #else /* !HANDLE_MULTIBYTE */
378 int
379 rl_forward_char (int count, int key)
380 {
381 return (rl_forward_byte (count, key));
382 }
383 #endif /* !HANDLE_MULTIBYTE */
384
385 /* Backwards compatibility. */
386 int
387 rl_forward (int count, int key)
388 {
389 return (rl_forward_char (count, key));
390 }
391
392 /* Move backward COUNT bytes. */
393 int
394 rl_backward_byte (int count, int key)
395 {
396 if (count < 0)
397 return (rl_forward_byte (-count, key));
398
399 if (count > 0)
400 {
401 if (rl_point < count)
402 {
403 rl_point = 0;
404 rl_ding ();
405 }
406 else
407 rl_point -= count;
408 }
409
410 if (rl_point < 0)
411 rl_point = 0;
412
413 return 0;
414 }
415
416 #if defined (HANDLE_MULTIBYTE)
417 /* Move backward COUNT characters. */
418 int
419 rl_backward_char (int count, int key)
420 {
421 int point;
422
423 if (MB_CUR_MAX == 1 || rl_byte_oriented)
424 return (rl_backward_byte (count, key));
425
426 if (count < 0)
427 return (rl_forward_char (-count, key));
428
429 if (count > 0)
430 {
431 point = rl_point;
432
433 while (count > 0 && point > 0)
434 {
435 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
436 count--;
437 }
438 if (count > 0)
439 {
440 rl_point = 0;
441 rl_ding ();
442 }
443 else
444 rl_point = point;
445 }
446
447 return 0;
448 }
449 #else
450 int
451 rl_backward_char (int count, int key)
452 {
453 return (rl_backward_byte (count, key));
454 }
455 #endif
456
457 /* Backwards compatibility. */
458 int
459 rl_backward (int count, int key)
460 {
461 return (rl_backward_char (count, key));
462 }
463
464 /* Move to the beginning of the line. */
465 int
466 rl_beg_of_line (int count, int key)
467 {
468 rl_point = 0;
469 return 0;
470 }
471
472 /* Move to the end of the line. */
473 int
474 rl_end_of_line (int count, int key)
475 {
476 rl_point = rl_end;
477 return 0;
478 }
479
480 /* Move forward a word. We do what Emacs does. Handles multibyte chars. */
481 int
482 rl_forward_word (int count, int key)
483 {
484 int c;
485
486 if (count < 0)
487 return (rl_backward_word (-count, key));
488
489 while (count)
490 {
491 if (rl_point > rl_end)
492 rl_point = rl_end;
493 if (rl_point == rl_end)
494 return 0;
495
496 /* If we are not in a word, move forward until we are in one.
497 Then, move forward until we hit a non-alphabetic character. */
498 c = _rl_char_value (rl_line_buffer, rl_point);
499
500 if (_rl_walphabetic (c) == 0)
501 {
502 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
503 while (rl_point < rl_end)
504 {
505 c = _rl_char_value (rl_line_buffer, rl_point);
506 if (_rl_walphabetic (c))
507 break;
508 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
509 }
510 }
511
512 if (rl_point > rl_end)
513 rl_point = rl_end;
514 if (rl_point == rl_end)
515 return 0;
516
517 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
518 while (rl_point < rl_end)
519 {
520 c = _rl_char_value (rl_line_buffer, rl_point);
521 if (_rl_walphabetic (c) == 0)
522 break;
523 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
524 }
525
526 --count;
527 }
528
529 return 0;
530 }
531
532 /* Move backward a word. We do what Emacs does. Handles multibyte chars. */
533 int
534 rl_backward_word (int count, int key)
535 {
536 int c, p;
537
538 if (count < 0)
539 return (rl_forward_word (-count, key));
540
541 while (count)
542 {
543 if (rl_point == 0)
544 return 0;
545
546 /* Like rl_forward_word (), except that we look at the characters
547 just before point. */
548
549 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
550 c = _rl_char_value (rl_line_buffer, p);
551
552 if (_rl_walphabetic (c) == 0)
553 {
554 rl_point = p;
555 while (rl_point > 0)
556 {
557 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
558 c = _rl_char_value (rl_line_buffer, p);
559 if (_rl_walphabetic (c))
560 break;
561 rl_point = p;
562 }
563 }
564
565 while (rl_point)
566 {
567 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
568 c = _rl_char_value (rl_line_buffer, p);
569 if (_rl_walphabetic (c) == 0)
570 break;
571 else
572 rl_point = p;
573 }
574
575 --count;
576 }
577
578 return 0;
579 }
580
581 /* Clear the current line. Numeric argument to C-l does this. */
582 int
583 rl_refresh_line (int ignore1, int ignore2)
584 {
585 _rl_refresh_line ();
586 rl_display_fixed = 1;
587 return 0;
588 }
589
590 /* C-l typed to a line without quoting clears the screen, and then reprints
591 the prompt and the current input line. Given a numeric arg, redraw only
592 the current line. */
593 int
594 rl_clear_screen (int count, int key)
595 {
596 if (rl_explicit_arg)
597 {
598 rl_refresh_line (count, key);
599 return 0;
600 }
601
602 _rl_clear_screen (0); /* calls termcap function to clear screen */
603 rl_keep_mark_active ();
604 rl_forced_update_display ();
605 rl_display_fixed = 1;
606
607 return 0;
608 }
609
610 int
611 rl_clear_display (int count, int key)
612 {
613 _rl_clear_screen (1); /* calls termcap function to clear screen and scrollback buffer */
614 rl_forced_update_display ();
615 rl_display_fixed = 1;
616
617 return 0;
618 }
619
620 int
621 rl_previous_screen_line (int count, int key)
622 {
623 int c;
624
625 c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1);
626 return (rl_backward_char (c, key));
627 }
628
629 int
630 rl_next_screen_line (int count, int key)
631 {
632 int c;
633
634 c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1);
635 return (rl_forward_char (c, key));
636 }
637
638 int
639 rl_skip_csi_sequence (int count, int key)
640 {
641 int ch;
642
643 RL_SETSTATE (RL_STATE_MOREINPUT);
644 do
645 ch = rl_read_key ();
646 while (ch >= 0x20 && ch < 0x40);
647 RL_UNSETSTATE (RL_STATE_MOREINPUT);
648
649 return (ch < 0);
650 }
651
652 int
653 rl_arrow_keys (int count, int key)
654 {
655 int ch;
656
657 RL_SETSTATE(RL_STATE_MOREINPUT);
658 ch = rl_read_key ();
659 RL_UNSETSTATE(RL_STATE_MOREINPUT);
660 if (ch < 0)
661 return (1);
662
663 switch (_rl_to_upper (ch))
664 {
665 case 'A':
666 rl_get_previous_history (count, ch);
667 break;
668
669 case 'B':
670 rl_get_next_history (count, ch);
671 break;
672
673 case 'C':
674 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
675 rl_forward_char (count, ch);
676 else
677 rl_forward_byte (count, ch);
678 break;
679
680 case 'D':
681 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
682 rl_backward_char (count, ch);
683 else
684 rl_backward_byte (count, ch);
685 break;
686
687 default:
688 rl_ding ();
689 }
690
691 return 0;
692 }
693
694 /* **************************************************************** */
695 /* */
696 /* Text commands */
697 /* */
698 /* **************************************************************** */
699
700 #ifdef HANDLE_MULTIBYTE
701 static char pending_bytes[MB_LEN_MAX];
702 static int pending_bytes_length = 0;
703 static mbstate_t ps = {0};
704 #endif
705
706 /* Insert the character C at the current location, moving point forward.
707 If C introduces a multibyte sequence, we read the whole sequence and
708 then insert the multibyte char into the line buffer.
709 If C == 0, we immediately insert any pending partial multibyte character,
710 assuming that we have read a character that doesn't map to self-insert.
711 This doesn't completely handle characters that are part of a multibyte
712 character but map to editing functions. */
713 int
714 _rl_insert_char (int count, int c)
715 {
716 register int i;
717 char *string;
718 #ifdef HANDLE_MULTIBYTE
719 int string_size;
720 char incoming[MB_LEN_MAX + 1];
721 int incoming_length = 0;
722 mbstate_t ps_back;
723 static int stored_count = 0;
724 #endif
725
726 #if !defined (HANDLE_MULTIBYTE)
727 if (count <= 0)
728 return 0;
729 #else
730 if (count < 0)
731 return 0;
732 if (count == 0)
733 {
734 if (pending_bytes_length == 0)
735 return 0;
736 if (stored_count <= 0)
737 stored_count = count;
738 else
739 count = stored_count;
740
741 memcpy (incoming, pending_bytes, pending_bytes_length);
742 incoming[pending_bytes_length] = '\0';
743 incoming_length = pending_bytes_length;
744 pending_bytes_length = 0;
745 memset (&ps, 0, sizeof (mbstate_t));
746 }
747 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
748 {
749 incoming[0] = c;
750 incoming[1] = '\0';
751 incoming_length = 1;
752 }
753 else if (_rl_utf8locale && (c & 0x80) == 0)
754 {
755 if (pending_bytes_length)
756 _rl_insert_char (0, 0);
757
758 incoming[0] = c;
759 incoming[1] = '\0';
760 incoming_length = 1;
761 }
762 else
763 {
764 WCHAR_T wc;
765 size_t ret;
766
767 if (stored_count <= 0)
768 stored_count = count;
769 else
770 count = stored_count;
771
772 ps_back = ps;
773 pending_bytes[pending_bytes_length++] = c;
774 ret = MBRTOWC (&wc, pending_bytes, pending_bytes_length, &ps);
775
776 if (ret == (size_t)-2)
777 {
778 /* Bytes too short to compose character, try to wait for next byte.
779 Restore the state of the byte sequence, because in this case the
780 effect of mbstate is undefined. */
781 ps = ps_back;
782 return 1;
783 }
784 else if (ret == (size_t)-1)
785 {
786 /* Invalid byte sequence for the current locale. Treat first byte
787 as a single character. */
788 incoming[0] = pending_bytes[0];
789 incoming[1] = '\0';
790 incoming_length = 1;
791 pending_bytes_length--;
792 if (pending_bytes_length)
793 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
794 /* Clear the state of the byte sequence, because in this case the
795 effect of mbstate is undefined. */
796 memset (&ps, 0, sizeof (mbstate_t));
797 }
798 else if (ret == (size_t)0)
799 {
800 incoming[0] = '\0';
801 incoming_length = 0;
802 pending_bytes_length--;
803 /* Clear the state of the byte sequence, because in this case the
804 effect of mbstate is undefined. */
805 memset (&ps, 0, sizeof (mbstate_t));
806 }
807 else if (ret == 1)
808 {
809 incoming[0] = pending_bytes[0];
810 incoming[incoming_length = 1] = '\0';
811 pending_bytes_length = 0;
812 }
813 else
814 {
815 /* We successfully read a single multibyte character. */
816 memcpy (incoming, pending_bytes, pending_bytes_length);
817 incoming[pending_bytes_length] = '\0';
818 incoming_length = pending_bytes_length;
819 pending_bytes_length = 0;
820 }
821 }
822 #endif /* HANDLE_MULTIBYTE */
823
824 /* If we can optimize, then do it. But don't let people crash
825 readline because of extra large arguments. */
826 if (count > 1 && count <= TEXT_COUNT_MAX)
827 {
828 #if defined (HANDLE_MULTIBYTE)
829 string_size = count * incoming_length;
830 string = (char *)xmalloc (1 + string_size);
831
832 i = 0;
833 while (i < string_size)
834 {
835 if (incoming_length == 1)
836 string[i++] = *incoming;
837 else
838 {
839 strncpy (string + i, incoming, incoming_length);
840 i += incoming_length;
841 }
842 }
843 incoming_length = 0;
844 stored_count = 0;
845 #else /* !HANDLE_MULTIBYTE */
846 string = (char *)xmalloc (1 + count);
847
848 for (i = 0; i < count; i++)
849 string[i] = c;
850 #endif /* !HANDLE_MULTIBYTE */
851
852 string[i] = '\0';
853 rl_insert_text (string);
854 xfree (string);
855
856 #if defined (HANDLE_MULTIBYTE)
857 return (pending_bytes_length != 0);
858 #else
859 return 0;
860 #endif
861 }
862
863 if (count > TEXT_COUNT_MAX)
864 {
865 int decreaser;
866 #if defined (HANDLE_MULTIBYTE)
867 string_size = incoming_length * TEXT_COUNT_MAX;
868 string = (char *)xmalloc (1 + string_size);
869
870 i = 0;
871 while (i < string_size)
872 {
873 if (incoming_length == 1)
874 string[i++] = *incoming;
875 else
876 {
877 strncpy (string + i, incoming, incoming_length);
878 i += incoming_length;
879 }
880 }
881
882 while (count)
883 {
884 decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
885 string[decreaser*incoming_length] = '\0';
886 rl_insert_text (string);
887 count -= decreaser;
888 }
889
890 xfree (string);
891 incoming_length = 0;
892 stored_count = 0;
893
894 return (pending_bytes_length != 0);
895 #else /* !HANDLE_MULTIBYTE */
896 char str[TEXT_COUNT_MAX+1];
897
898 for (i = 0; i < TEXT_COUNT_MAX; i++)
899 str[i] = c;
900
901 while (count)
902 {
903 decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
904 str[decreaser] = '\0';
905 rl_insert_text (str);
906 count -= decreaser;
907 }
908
909 return 0;
910 #endif /* !HANDLE_MULTIBYTE */
911 }
912
913 if (MB_CUR_MAX == 1 || rl_byte_oriented)
914 {
915 /* We are inserting a single character.
916 If there is pending input, then make a string of all of the
917 pending characters that are bound to rl_insert, and insert
918 them all. Don't do this if we're current reading input from
919 a macro. */
920 if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ())
921 _rl_insert_typein (c);
922 else
923 {
924 /* Inserting a single character. */
925 char str[2];
926
927 str[1] = '\0';
928 str[0] = c;
929 rl_insert_text (str);
930 }
931 }
932 #if defined (HANDLE_MULTIBYTE)
933 else
934 {
935 rl_insert_text (incoming);
936 stored_count = 0;
937 }
938
939 return (pending_bytes_length != 0);
940 #else
941 return 0;
942 #endif
943 }
944
945 /* Overwrite the character at point (or next COUNT characters) with C.
946 If C introduces a multibyte character sequence, read the entire sequence
947 before starting the overwrite loop. */
948 int
949 _rl_overwrite_char (int count, int c)
950 {
951 int i;
952 #if defined (HANDLE_MULTIBYTE)
953 char mbkey[MB_LEN_MAX];
954 int k;
955
956 /* Read an entire multibyte character sequence to insert COUNT times. */
957 k = 1;
958 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
959 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
960 if (k < 0)
961 return 1;
962 #endif
963
964 rl_begin_undo_group ();
965
966 for (i = 0; i < count; i++)
967 {
968 #if defined (HANDLE_MULTIBYTE)
969 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
970 rl_insert_text (mbkey);
971 else
972 #endif
973 _rl_insert_char (1, c);
974
975 if (rl_point < rl_end)
976 rl_delete (1, c);
977 }
978
979 rl_end_undo_group ();
980
981 return 0;
982 }
983
984 int
985 rl_insert (int count, int c)
986 {
987 int r, n, x;
988
989 r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (count, c) : _rl_overwrite_char (count, c);
990
991 /* XXX -- attempt to batch-insert pending input that maps to self-insert */
992 x = 0;
993 n = (unsigned short)-2;
994 while (_rl_optimize_typeahead &&
995 rl_num_chars_to_read == 0 &&
996 (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
997 _rl_pushed_input_available () == 0 &&
998 _rl_input_queued (0) &&
999 (n = rl_read_key ()) > 0 &&
1000 _rl_keymap[(unsigned char)n].type == ISFUNC &&
1001 _rl_keymap[(unsigned char)n].function == rl_insert)
1002 {
1003 r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (1, n) : _rl_overwrite_char (1, n);
1004 /* _rl_insert_char keeps its own set of pending characters to compose a
1005 complete multibyte character, and only returns 1 if it sees a character
1006 that's part of a multibyte character but too short to complete one. We
1007 can try to read another character in the hopes that we will get the
1008 next one or just punt. Right now we try to read another character.
1009 We don't want to call rl_insert_next if _rl_insert_char has already
1010 stored the character in the pending_bytes array because that will
1011 result in doubled input. */
1012 n = (unsigned short)-2;
1013 x++; /* count of bytes of typeahead read, currently unused */
1014 if (r == 1) /* read partial multibyte character */
1015 continue;
1016 if (rl_done || r != 0)
1017 break;
1018 }
1019
1020 /* If we didn't insert n and there are pending bytes, we need to insert
1021 them if _rl_insert_char didn't do that on its own. */
1022 if (r == 1 && rl_insert_mode == RL_IM_INSERT)
1023 r = _rl_insert_char (0, 0); /* flush partial multibyte char */
1024
1025 if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */
1026 {
1027 /* setting rl_pending_input inhibits setting rl_last_func so we do it
1028 ourselves here */
1029 rl_last_func = rl_insert;
1030 _rl_reset_argument ();
1031 rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
1032 r = rl_execute_next (n);
1033 }
1034 return r;
1035 }
1036
1037 /* Insert the next typed character verbatim. */
1038 static int
1039 _rl_insert_next (int count)
1040 {
1041 int c;
1042
1043 RL_SETSTATE(RL_STATE_MOREINPUT);
1044 c = rl_read_key ();
1045 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1046
1047 if (c < 0)
1048 return 1;
1049
1050 if (RL_ISSTATE (RL_STATE_MACRODEF))
1051 _rl_add_macro_char (c);
1052
1053 #if defined (HANDLE_SIGNALS)
1054 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
1055 _rl_restore_tty_signals ();
1056 #endif
1057
1058 return (_rl_insert_char (count, c));
1059 }
1060
1061 #if defined (READLINE_CALLBACKS)
1062 static int
1063 _rl_insert_next_callback (_rl_callback_generic_arg *data)
1064 {
1065 int count, r;
1066
1067 count = data->count;
1068 r = 0;
1069
1070 if (count < 0)
1071 {
1072 data->count++;
1073 r = _rl_insert_next (1);
1074 _rl_want_redisplay = 1;
1075 /* If we should keep going, leave the callback function installed */
1076 if (data->count < 0 && r == 0)
1077 return r;
1078 count = 0; /* data->count == 0 || r != 0; force break below */
1079 }
1080
1081 /* Deregister function, let rl_callback_read_char deallocate data */
1082 _rl_callback_func = 0;
1083 _rl_want_redisplay = 1;
1084
1085 if (count == 0)
1086 return r;
1087
1088 return _rl_insert_next (count);
1089 }
1090 #endif
1091
1092 int
1093 rl_quoted_insert (int count, int key)
1094 {
1095 int r;
1096
1097 /* Let's see...should the callback interface futz with signal handling? */
1098 #if defined (HANDLE_SIGNALS)
1099 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
1100 _rl_disable_tty_signals ();
1101 #endif
1102
1103 #if defined (READLINE_CALLBACKS)
1104 if (RL_ISSTATE (RL_STATE_CALLBACK))
1105 {
1106 _rl_callback_data = _rl_callback_data_alloc (count);
1107 _rl_callback_func = _rl_insert_next_callback;
1108 return (0);
1109 }
1110 #endif
1111
1112 /* A negative count means to quote the next -COUNT characters. */
1113 if (count < 0)
1114 {
1115 do
1116 r = _rl_insert_next (1);
1117 while (r == 0 && ++count < 0);
1118 }
1119 else
1120 r = _rl_insert_next (count);
1121
1122 if (r == 1)
1123 _rl_insert_char (0, 0); /* insert partial multibyte character */
1124
1125 return r;
1126 }
1127
1128 /* Insert a tab character. */
1129 int
1130 rl_tab_insert (int count, int key)
1131 {
1132 return (_rl_insert_char (count, '\t'));
1133 }
1134
1135 /* What to do when a NEWLINE is pressed. We accept the whole line.
1136 KEY is the key that invoked this command. I guess it could have
1137 meaning in the future. */
1138 int
1139 rl_newline (int count, int key)
1140 {
1141 if (rl_mark_active_p ())
1142 {
1143 rl_deactivate_mark ();
1144 (*rl_redisplay_function) ();
1145 _rl_want_redisplay = 0;
1146 }
1147
1148 rl_done = 1;
1149
1150 if (_rl_history_preserve_point)
1151 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
1152
1153 RL_SETSTATE(RL_STATE_DONE);
1154
1155 #if defined (VI_MODE)
1156 if (rl_editing_mode == vi_mode)
1157 {
1158 _rl_vi_done_inserting ();
1159 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
1160 _rl_vi_reset_last ();
1161 }
1162 #endif /* VI_MODE */
1163
1164 /* If we've been asked to erase empty lines, suppress the final update,
1165 since _rl_update_final calls rl_crlf(). */
1166 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
1167 return 0;
1168
1169 if (_rl_echoing_p)
1170 _rl_update_final ();
1171 return 0;
1172 }
1173
1174 /* What to do for some uppercase characters, like meta characters,
1175 and some characters appearing in emacs_ctlx_keymap. This function
1176 is just a stub, you bind keys to it and the code in _rl_dispatch ()
1177 is special cased. */
1178 int
1179 rl_do_lowercase_version (int ignore1, int ignore2)
1180 {
1181 return 99999; /* prevent from being combined with _rl_null_function */
1182 }
1183
1184 /* This is different from what vi does, so the code's not shared. Emacs
1185 rubout in overwrite mode has one oddity: it replaces a control
1186 character that's displayed as two characters (^X) with two spaces. */
1187 int
1188 _rl_overwrite_rubout (int count, int key)
1189 {
1190 int opoint;
1191 int i, l;
1192
1193 if (rl_point == 0)
1194 {
1195 rl_ding ();
1196 return 1;
1197 }
1198
1199 opoint = rl_point;
1200
1201 /* L == number of spaces to insert */
1202 for (i = l = 0; i < count; i++)
1203 {
1204 rl_backward_char (1, key);
1205 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
1206 }
1207
1208 rl_begin_undo_group ();
1209
1210 if (count > 1 || rl_explicit_arg)
1211 rl_kill_text (opoint, rl_point);
1212 else
1213 rl_delete_text (opoint, rl_point);
1214
1215 /* Emacs puts point at the beginning of the sequence of spaces. */
1216 if (rl_point < rl_end)
1217 {
1218 opoint = rl_point;
1219 _rl_insert_char (l, ' ');
1220 rl_point = opoint;
1221 }
1222
1223 rl_end_undo_group ();
1224
1225 return 0;
1226 }
1227
1228 /* Rubout the character behind point. */
1229 int
1230 rl_rubout (int count, int key)
1231 {
1232 if (count < 0)
1233 return (rl_delete (-count, key));
1234
1235 if (!rl_point)
1236 {
1237 rl_ding ();
1238 return 1;
1239 }
1240
1241 if (rl_insert_mode == RL_IM_OVERWRITE)
1242 return (_rl_overwrite_rubout (count, key));
1243
1244 return (_rl_rubout_char (count, key));
1245 }
1246
1247 int
1248 _rl_rubout_char (int count, int key)
1249 {
1250 int orig_point;
1251 unsigned char c;
1252
1253 /* Duplicated code because this is called from other parts of the library. */
1254 if (count < 0)
1255 return (rl_delete (-count, key));
1256
1257 if (rl_point == 0)
1258 {
1259 rl_ding ();
1260 return 1;
1261 }
1262
1263 orig_point = rl_point;
1264 if (count > 1 || rl_explicit_arg)
1265 {
1266 rl_backward_char (count, key);
1267 rl_kill_text (orig_point, rl_point);
1268 }
1269 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1270 {
1271 c = rl_line_buffer[--rl_point];
1272 rl_delete_text (rl_point, orig_point);
1273 /* The erase-at-end-of-line hack is of questionable merit now. */
1274 if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos && _rl_last_v_pos == 0)
1275 {
1276 int l;
1277 l = rl_character_len (c, rl_point);
1278 if (_rl_last_c_pos >= l)
1279 _rl_erase_at_end_of_line (l);
1280 }
1281 }
1282 else
1283 {
1284 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1285 rl_delete_text (rl_point, orig_point);
1286 }
1287
1288 return 0;
1289 }
1290
1291 /* Delete the character under the cursor. Given a numeric argument,
1292 kill that many characters instead. */
1293 int
1294 rl_delete (int count, int key)
1295 {
1296 int xpoint;
1297
1298 if (count < 0)
1299 return (_rl_rubout_char (-count, key));
1300
1301 if (rl_point == rl_end)
1302 {
1303 rl_ding ();
1304 return 1;
1305 }
1306
1307 if (count > 1 || rl_explicit_arg)
1308 {
1309 xpoint = rl_point;
1310 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1311 rl_forward_char (count, key);
1312 else
1313 rl_forward_byte (count, key);
1314
1315 rl_kill_text (xpoint, rl_point);
1316 rl_point = xpoint;
1317 }
1318 else
1319 {
1320 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1321 rl_delete_text (rl_point, xpoint);
1322 }
1323 return 0;
1324 }
1325
1326 /* Delete the character under the cursor, unless the insertion
1327 point is at the end of the line, in which case the character
1328 behind the cursor is deleted. COUNT is obeyed and may be used
1329 to delete forward or backward that many characters. */
1330 int
1331 rl_rubout_or_delete (int count, int key)
1332 {
1333 if (rl_end != 0 && rl_point == rl_end)
1334 return (_rl_rubout_char (count, key));
1335 else
1336 return (rl_delete (count, key));
1337 }
1338
1339 /* Delete all spaces and tabs around point. */
1340 int
1341 rl_delete_horizontal_space (int count, int ignore)
1342 {
1343 int start;
1344
1345 while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1346 rl_point--;
1347
1348 start = rl_point;
1349
1350 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1351 rl_point++;
1352
1353 if (start != rl_point)
1354 {
1355 rl_delete_text (start, rl_point);
1356 rl_point = start;
1357 }
1358
1359 if (rl_point < 0)
1360 rl_point = 0;
1361
1362 return 0;
1363 }
1364
1365 /* Like the tcsh editing function delete-char-or-list. The eof character
1366 is caught before this is invoked, so this really does the same thing as
1367 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1368 int
1369 rl_delete_or_show_completions (int count, int key)
1370 {
1371 if (rl_end != 0 && rl_point == rl_end)
1372 return (rl_possible_completions (count, key));
1373 else
1374 return (rl_delete (count, key));
1375 }
1376
1377 #ifndef RL_COMMENT_BEGIN_DEFAULT
1378 #define RL_COMMENT_BEGIN_DEFAULT "#"
1379 #endif
1380
1381 /* Turn the current line into a comment in shell history.
1382 A K*rn shell style function. */
1383 int
1384 rl_insert_comment (int count, int key)
1385 {
1386 char *rl_comment_text;
1387 int rl_comment_len;
1388
1389 rl_beg_of_line (1, key);
1390 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1391
1392 if (rl_explicit_arg == 0)
1393 rl_insert_text (rl_comment_text);
1394 else
1395 {
1396 rl_comment_len = strlen (rl_comment_text);
1397 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1398 rl_delete_text (rl_point, rl_point + rl_comment_len);
1399 else
1400 rl_insert_text (rl_comment_text);
1401 }
1402
1403 (*rl_redisplay_function) ();
1404 rl_newline (1, '\n');
1405
1406 return (0);
1407 }
1408
1409 /* **************************************************************** */
1410 /* */
1411 /* Changing Case */
1412 /* */
1413 /* **************************************************************** */
1414
1415 /* The three kinds of things that we know how to do. */
1416 #define UpCase 1
1417 #define DownCase 2
1418 #define CapCase 3
1419
1420 /* Uppercase the word at point. */
1421 int
1422 rl_upcase_word (int count, int key)
1423 {
1424 return (rl_change_case (count, UpCase));
1425 }
1426
1427 /* Lowercase the word at point. */
1428 int
1429 rl_downcase_word (int count, int key)
1430 {
1431 return (rl_change_case (count, DownCase));
1432 }
1433
1434 /* Upcase the first letter, downcase the rest. */
1435 int
1436 rl_capitalize_word (int count, int key)
1437 {
1438 return (rl_change_case (count, CapCase));
1439 }
1440
1441 /* The meaty function.
1442 Change the case of COUNT words, performing OP on them.
1443 OP is one of UpCase, DownCase, or CapCase.
1444 If a negative argument is given, leave point where it started,
1445 otherwise, leave it where it moves to. */
1446 static int
1447 rl_change_case (int count, int op)
1448 {
1449 int start, next, end;
1450 int inword, nc, nop;
1451 WCHAR_T c;
1452 unsigned char uc;
1453 #if defined (HANDLE_MULTIBYTE)
1454 WCHAR_T wc, nwc;
1455 char mb[MB_LEN_MAX+1];
1456 size_t m, mlen;
1457 mbstate_t mps;
1458 #endif
1459
1460 start = rl_point;
1461 rl_forward_word (count, 0);
1462 end = rl_point;
1463
1464 if (op != UpCase && op != DownCase && op != CapCase)
1465 {
1466 rl_ding ();
1467 return 1;
1468 }
1469
1470 if (count < 0)
1471 SWAP (start, end);
1472
1473 #if defined (HANDLE_MULTIBYTE)
1474 memset (&mps, 0, sizeof (mbstate_t));
1475 #endif
1476
1477 /* We are going to modify some text, so let's prepare to undo it. */
1478 rl_modifying (start, end);
1479
1480 inword = 0;
1481 while (start < end)
1482 {
1483 c = _rl_char_value (rl_line_buffer, start);
1484 /* This assumes that the upper and lower case versions are the same width. */
1485 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1486
1487 if (_rl_walphabetic (c) == 0)
1488 {
1489 inword = 0;
1490 start = next;
1491 continue;
1492 }
1493
1494 if (op == CapCase)
1495 {
1496 nop = inword ? DownCase : UpCase;
1497 inword = 1;
1498 }
1499 else
1500 nop = op;
1501 /* Can't check isascii here; some languages (e.g, Turkish) have
1502 multibyte upper and lower case equivalents of single-byte ascii
1503 characters */
1504 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1505 {
1506 change_singlebyte:
1507 uc = c;
1508 nc = (nop == UpCase) ? _rl_to_upper (uc) : _rl_to_lower (uc);
1509 rl_line_buffer[start] = nc;
1510 }
1511 #if defined (HANDLE_MULTIBYTE)
1512 else
1513 {
1514 m = MBRTOWC (&wc, rl_line_buffer + start, end - start, &mps);
1515 if (MB_INVALIDCH (m))
1516 {
1517 c = rl_line_buffer[start];
1518 next = start + 1; /* potentially redundant */
1519 goto change_singlebyte;
1520 }
1521 else if (MB_NULLWCH (m))
1522 {
1523 start = next; /* don't bother with null wide characters */
1524 continue;
1525 }
1526 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1527 if (nwc != wc) /* just skip unchanged characters */
1528 {
1529 char *s, *e;
1530 mbstate_t ts;
1531
1532 memset (&ts, 0, sizeof (mbstate_t));
1533 mlen = WCRTOMB (mb, nwc, &ts);
1534
1535 if (MB_INVALIDCH (mlen))
1536 {
1537 nwc = wc;
1538 memset (&ts, 0, sizeof (mbstate_t));
1539 mlen = WCRTOMB (mb, nwc, &ts);
1540 if (MB_INVALIDCH (mlen)) /* should not happen */
1541 strncpy (mb, rl_line_buffer + start, mlen = m);
1542 }
1543 if (mlen > 0)
1544 mb[mlen] = '\0';
1545 /* what to do if m != mlen? adjust below */
1546 /* m == length of old char, mlen == length of new char */
1547 s = rl_line_buffer + start;
1548 e = rl_line_buffer + rl_end;
1549 if (m == mlen)
1550 memcpy (s, mb, mlen);
1551 else if (m > mlen)
1552 {
1553 memcpy (s, mb, mlen);
1554 memmove (s + mlen, s + m, (e - s) - m);
1555 next -= m - mlen; /* next char changes */
1556 end -= m - mlen; /* end of word changes */
1557 rl_end -= m - mlen; /* end of line changes */
1558 rl_line_buffer[rl_end] = 0;
1559 }
1560 else if (m < mlen)
1561 {
1562 rl_extend_line_buffer (rl_end + mlen + (e - s) - m + 2);
1563 s = rl_line_buffer + start; /* have to redo this */
1564 e = rl_line_buffer + rl_end;
1565 memmove (s + mlen, s + m, (e - s) - m);
1566 memcpy (s, mb, mlen);
1567 next += mlen - m; /* next char changes */
1568 end += mlen - m; /* end of word changes */
1569 rl_end += mlen - m; /* end of line changes */
1570 rl_line_buffer[rl_end] = 0;
1571 }
1572 }
1573 }
1574 #endif
1575
1576 start = next;
1577 }
1578
1579 rl_point = end;
1580 return 0;
1581 }
1582
1583 /* **************************************************************** */
1584 /* */
1585 /* Transposition */
1586 /* */
1587 /* **************************************************************** */
1588
1589 /* Transpose the words at point. If point is at the end of the line,
1590 transpose the two words before point. */
1591 int
1592 rl_transpose_words (int count, int key)
1593 {
1594 char *word1, *word2;
1595 int w1_beg, w1_end, w2_beg, w2_end;
1596 int orig_point, orig_end;
1597
1598 orig_point = rl_point;
1599 orig_end = rl_end;
1600
1601 if (!count)
1602 return 0;
1603
1604 /* Find the two words. */
1605 rl_forward_word (count, key);
1606 w2_end = rl_point;
1607 rl_backward_word (1, key);
1608 w2_beg = rl_point;
1609 rl_backward_word (count, key);
1610 w1_beg = rl_point;
1611 rl_forward_word (1, key);
1612 w1_end = rl_point;
1613
1614 /* Do some check to make sure that there really are two words. */
1615 if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1616 {
1617 rl_ding ();
1618 rl_point = orig_point;
1619 return 1;
1620 }
1621
1622 /* Get the text of the words. */
1623 word1 = rl_copy_text (w1_beg, w1_end);
1624 word2 = rl_copy_text (w2_beg, w2_end);
1625
1626 /* We are about to do many insertions and deletions. Remember them
1627 as one operation. */
1628 rl_begin_undo_group ();
1629
1630 /* Do the stuff at word2 first, so that we don't have to worry
1631 about word1 moving. */
1632 rl_point = w2_beg;
1633 rl_delete_text (w2_beg, w2_end);
1634 rl_insert_text (word1);
1635
1636 rl_point = w1_beg;
1637 rl_delete_text (w1_beg, w1_end);
1638 rl_insert_text (word2);
1639
1640 /* This is exactly correct since the text before this point has not
1641 changed in length. */
1642 rl_point = w2_end;
1643 rl_end = orig_end; /* just make sure */
1644
1645 /* I think that does it. */
1646 rl_end_undo_group ();
1647 xfree (word1);
1648 xfree (word2);
1649
1650 return 0;
1651 }
1652
1653 /* Transpose the characters at point. If point is at the end of the line,
1654 then transpose the characters before point. */
1655 int
1656 rl_transpose_chars (int count, int key)
1657 {
1658 #if defined (HANDLE_MULTIBYTE)
1659 char *dummy;
1660 int i;
1661 #else
1662 char dummy[2];
1663 #endif
1664 int char_length, prev_point;
1665
1666 if (count == 0)
1667 return 0;
1668
1669 if (!rl_point || rl_end < 2)
1670 {
1671 rl_ding ();
1672 return 1;
1673 }
1674
1675 rl_begin_undo_group ();
1676
1677 if (rl_point == rl_end)
1678 {
1679 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1680 count = 1;
1681 }
1682
1683 prev_point = rl_point;
1684 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1685
1686 #if defined (HANDLE_MULTIBYTE)
1687 char_length = prev_point - rl_point;
1688 dummy = (char *)xmalloc (char_length + 1);
1689 for (i = 0; i < char_length; i++)
1690 dummy[i] = rl_line_buffer[rl_point + i];
1691 dummy[i] = '\0';
1692 #else
1693 dummy[0] = rl_line_buffer[rl_point];
1694 dummy[char_length = 1] = '\0';
1695 #endif
1696
1697 rl_delete_text (rl_point, rl_point + char_length);
1698
1699 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1700
1701 _rl_fix_point (0);
1702 rl_insert_text (dummy);
1703 rl_end_undo_group ();
1704
1705 #if defined (HANDLE_MULTIBYTE)
1706 xfree (dummy);
1707 #endif
1708
1709 return 0;
1710 }
1711
1712 /* **************************************************************** */
1713 /* */
1714 /* Character Searching */
1715 /* */
1716 /* **************************************************************** */
1717
1718 int
1719 #if defined (HANDLE_MULTIBYTE)
1720 _rl_char_search_internal (int count, int dir, char *smbchar, int len)
1721 #else
1722 _rl_char_search_internal (int count, int dir, int schar)
1723 #endif
1724 {
1725 int pos, inc;
1726 #if defined (HANDLE_MULTIBYTE)
1727 int prepos;
1728 #endif
1729
1730 if (dir == 0)
1731 return 1;
1732
1733 pos = rl_point;
1734 inc = (dir < 0) ? -1 : 1;
1735 while (count)
1736 {
1737 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1738 {
1739 rl_ding ();
1740 return 1;
1741 }
1742
1743 #if defined (HANDLE_MULTIBYTE)
1744 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1745 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1746 #else
1747 pos += inc;
1748 #endif
1749 do
1750 {
1751 #if defined (HANDLE_MULTIBYTE)
1752 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1753 #else
1754 if (rl_line_buffer[pos] == schar)
1755 #endif
1756 {
1757 count--;
1758 if (dir < 0)
1759 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1760 : pos;
1761 else
1762 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1763 : pos;
1764 break;
1765 }
1766 #if defined (HANDLE_MULTIBYTE)
1767 prepos = pos;
1768 #endif
1769 }
1770 #if defined (HANDLE_MULTIBYTE)
1771 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1772 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1773 #else
1774 while ((dir < 0) ? pos-- : ++pos < rl_end);
1775 #endif
1776 }
1777 return (0);
1778 }
1779
1780 /* Search COUNT times for a character read from the current input stream.
1781 FDIR is the direction to search if COUNT is non-negative; otherwise
1782 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1783 that there are two separate versions of this function. */
1784 #if defined (HANDLE_MULTIBYTE)
1785 static int
1786 _rl_char_search (int count, int fdir, int bdir)
1787 {
1788 char mbchar[MB_LEN_MAX];
1789 int mb_len;
1790
1791 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1792
1793 if (mb_len <= 0)
1794 return 1;
1795
1796 if (count < 0)
1797 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1798 else
1799 return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1800 }
1801 #else /* !HANDLE_MULTIBYTE */
1802 static int
1803 _rl_char_search (int count, int fdir, int bdir)
1804 {
1805 int c;
1806
1807 c = _rl_bracketed_read_key ();
1808 if (c < 0)
1809 return 1;
1810
1811 if (count < 0)
1812 return (_rl_char_search_internal (-count, bdir, c));
1813 else
1814 return (_rl_char_search_internal (count, fdir, c));
1815 }
1816 #endif /* !HANDLE_MULTIBYTE */
1817
1818 #if defined (READLINE_CALLBACKS)
1819 static int
1820 _rl_char_search_callback (_rl_callback_generic_arg *data)
1821 {
1822 _rl_callback_func = 0;
1823 _rl_want_redisplay = 1;
1824
1825 return (_rl_char_search (data->count, data->i1, data->i2));
1826 }
1827 #endif
1828
1829 int
1830 rl_char_search (int count, int key)
1831 {
1832 #if defined (READLINE_CALLBACKS)
1833 if (RL_ISSTATE (RL_STATE_CALLBACK))
1834 {
1835 _rl_callback_data = _rl_callback_data_alloc (count);
1836 _rl_callback_data->i1 = FFIND;
1837 _rl_callback_data->i2 = BFIND;
1838 _rl_callback_func = _rl_char_search_callback;
1839 return (0);
1840 }
1841 #endif
1842
1843 return (_rl_char_search (count, FFIND, BFIND));
1844 }
1845
1846 int
1847 rl_backward_char_search (int count, int key)
1848 {
1849 #if defined (READLINE_CALLBACKS)
1850 if (RL_ISSTATE (RL_STATE_CALLBACK))
1851 {
1852 _rl_callback_data = _rl_callback_data_alloc (count);
1853 _rl_callback_data->i1 = BFIND;
1854 _rl_callback_data->i2 = FFIND;
1855 _rl_callback_func = _rl_char_search_callback;
1856 return (0);
1857 }
1858 #endif
1859
1860 return (_rl_char_search (count, BFIND, FFIND));
1861 }
1862
1863 /* **************************************************************** */
1864 /* */
1865 /* The Mark and the Region. */
1866 /* */
1867 /* **************************************************************** */
1868
1869 /* Set the mark at POSITION. */
1870 int
1871 _rl_set_mark_at_pos (int position)
1872 {
1873 if (position < 0 || position > rl_end)
1874 return 1;
1875
1876 rl_mark = position;
1877 return 0;
1878 }
1879
1880 /* A bindable command to set the mark. */
1881 int
1882 rl_set_mark (int count, int key)
1883 {
1884 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1885 }
1886
1887 /* Exchange the position of mark and point. */
1888 int
1889 rl_exchange_point_and_mark (int count, int key)
1890 {
1891 if (rl_mark > rl_end)
1892 rl_mark = -1;
1893
1894 if (rl_mark < 0)
1895 {
1896 rl_ding ();
1897 rl_mark = 0; /* like _RL_FIX_POINT */
1898 return 1;
1899 }
1900 else
1901 {
1902 SWAP (rl_point, rl_mark);
1903 rl_activate_mark ();
1904 }
1905
1906 return 0;
1907 }
1908
1909 /* Active mark support */
1910
1911 /* Is the region active? */
1912 static int mark_active = 0;
1913
1914 /* Does the current command want the mark to remain active when it completes? */
1915 int _rl_keep_mark_active;
1916
1917 void
1918 rl_keep_mark_active (void)
1919 {
1920 _rl_keep_mark_active++;
1921 }
1922
1923 void
1924 rl_activate_mark (void)
1925 {
1926 mark_active = 1;
1927 rl_keep_mark_active ();
1928 }
1929
1930 void
1931 rl_deactivate_mark (void)
1932 {
1933 mark_active = 0;
1934 }
1935
1936 int
1937 rl_mark_active_p (void)
1938 {
1939 return (mark_active);
1940 }
1941
1942 /* **************************************************************** */
1943 /* */
1944 /* Reading a string entered from the keyboard */
1945 /* */
1946 /* **************************************************************** */
1947
1948 /* A very simple set of functions to read a string from the keyboard using
1949 the line buffer as temporary storage. The caller can set a completion
1950 function to perform completion on TAB and SPACE. */
1951
1952 /* XXX - this is all very similar to the search stuff but with a different
1953 CXT. */
1954
1955 static HIST_ENTRY *_rl_saved_line_for_readstr;
1956 _rl_readstr_cxt *_rl_rscxt;
1957
1958 _rl_readstr_cxt *
1959 _rl_rscxt_alloc (int flags)
1960 {
1961 _rl_readstr_cxt *cxt;
1962
1963 cxt = (_rl_readstr_cxt *)xmalloc (sizeof (_rl_readstr_cxt));
1964
1965 cxt->flags = flags;
1966
1967 cxt->save_point = rl_point;
1968 cxt->save_mark = rl_mark;
1969 cxt->save_line = where_history ();
1970
1971 cxt->prevc = cxt->lastc = 0;
1972
1973 cxt->compfunc = NULL;
1974
1975 return cxt;
1976 }
1977
1978 void
1979 _rl_rscxt_dispose (_rl_readstr_cxt *cxt, int flags)
1980 {
1981 xfree (cxt);
1982 }
1983
1984 /* This isn't used yet */
1985 void
1986 _rl_free_saved_readstr_line ()
1987 {
1988 if (_rl_saved_line_for_readstr)
1989 /* This doesn't free any saved undo list, if it needs to,
1990 rl_clear_history shows how to do it. */
1991 _rl_free_saved_line (_rl_saved_line_for_readstr);
1992 _rl_saved_line_for_readstr = (HIST_ENTRY *)NULL;
1993 }
1994
1995 void
1996 _rl_unsave_saved_readstr_line ()
1997 {
1998 if (_rl_saved_line_for_readstr)
1999 {
2000 _rl_free_undo_list (rl_undo_list);
2001 _rl_unsave_line (_rl_saved_line_for_readstr); /* restores rl_undo_list */
2002 }
2003 _rl_saved_line_for_readstr = (HIST_ENTRY *)NULL;
2004 }
2005
2006 _rl_readstr_cxt *
2007 _rl_readstr_init (int pchar, int flags)
2008 {
2009 _rl_readstr_cxt *cxt;
2010 char *p;
2011
2012 cxt = _rl_rscxt_alloc (flags);
2013
2014 _rl_saved_line_for_readstr = _rl_alloc_saved_line ();
2015 rl_undo_list = 0;
2016
2017 rl_line_buffer[0] = 0;
2018 rl_end = rl_point = 0;
2019
2020 p = _rl_make_prompt_for_search (pchar ? pchar : '@');
2021 cxt->flags |= READSTR_FREEPMT;
2022 rl_message ("%s", p);
2023 xfree (p);
2024
2025 RL_SETSTATE (RL_STATE_READSTR);
2026
2027 _rl_rscxt = cxt;
2028
2029 return cxt;
2030 }
2031
2032 int
2033 _rl_readstr_cleanup (_rl_readstr_cxt *cxt, int r)
2034 {
2035 _rl_rscxt_dispose (cxt, 0);
2036 _rl_rscxt = 0;
2037
2038 RL_UNSETSTATE (RL_STATE_READSTR);
2039
2040 return (r != 1);
2041 }
2042
2043 void
2044 _rl_readstr_restore (_rl_readstr_cxt *cxt)
2045 {
2046 _rl_unsave_saved_readstr_line (); /* restores rl_undo_list */
2047 rl_point = cxt->save_point;
2048 rl_mark = cxt->save_mark;
2049 if (cxt->flags & READSTR_FREEPMT)
2050 rl_restore_prompt (); /* _rl_make_prompt_for_search saved it */
2051 cxt->flags &= ~READSTR_FREEPMT;
2052 rl_clear_message ();
2053 _rl_fix_point (1);
2054 }
2055
2056 int
2057 _rl_readstr_sigcleanup (_rl_readstr_cxt *cxt, int r)
2058 {
2059 if (cxt->flags & READSTR_FREEPMT)
2060 rl_restore_prompt (); /* _rl_make_prompt_for_search saved it */
2061 cxt->flags &= ~READSTR_FREEPMT;
2062 return (_rl_readstr_cleanup (cxt, r));
2063 }
2064
2065 int
2066 _rl_readstr_getchar (_rl_readstr_cxt *cxt)
2067 {
2068 int c;
2069
2070 cxt->prevc = cxt->lastc;
2071
2072 /* Read a key and decide how to proceed. */
2073 RL_SETSTATE(RL_STATE_MOREINPUT);
2074 c = cxt->lastc = rl_read_key ();
2075 RL_UNSETSTATE(RL_STATE_MOREINPUT);
2076
2077 #if defined (HANDLE_MULTIBYTE)
2078 /* This ends up with C (and LASTC) being set to the last byte of the
2079 multibyte character. In most cases c == lastc == mb[0] */
2080 if (c >= 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2081 c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
2082 #endif
2083
2084 RL_CHECK_SIGNALS ();
2085 return c;
2086 }
2087
2088 /* Process just-read character C according to readstr context CXT. Return -1
2089 if the caller should abort the read, 0 if we should break out of the
2090 loop, and 1 if we should continue to read characters. This can perform
2091 completion on the string read so far (stored in rl_line_buffer) if the
2092 caller has set up a completion function. The completion function can
2093 return -1 to indicate that we should abort the read. If we return -1
2094 we will call _rl_readstr_restore to clean up the state, leaving the caller
2095 to free the context. */
2096 int
2097 _rl_readstr_dispatch (_rl_readstr_cxt *cxt, int c)
2098 {
2099 int n;
2100
2101 if (c < 0)
2102 c = CTRL ('C');
2103
2104 /* could consider looking up the function bound to they key and dispatching
2105 off that, but you want most characters inserted by default without having
2106 to quote. */
2107 switch (c)
2108 {
2109 case CTRL('W'):
2110 rl_unix_word_rubout (1, c);
2111 break;
2112
2113 case CTRL('U'):
2114 rl_unix_line_discard (1, c);
2115 break;
2116
2117 case CTRL('Q'):
2118 case CTRL('V'):
2119 n = rl_quoted_insert (1, c);
2120 if (n < 0)
2121 {
2122 _rl_readstr_restore (cxt);
2123 return -1;
2124 }
2125 cxt->lastc = (rl_point > 0) ? rl_line_buffer[rl_point - 1] : rl_line_buffer[0]; /* preserve prevc */
2126 break;
2127
2128 case RETURN:
2129 case NEWLINE:
2130 return 0;
2131
2132 case CTRL('H'):
2133 case RUBOUT:
2134 if (rl_point == 0)
2135 {
2136 _rl_readstr_restore (cxt);
2137 return -1;
2138 }
2139 _rl_rubout_char (1, c);
2140 break;
2141
2142 case CTRL('C'):
2143 case CTRL('G'):
2144 rl_ding ();
2145 _rl_readstr_restore (cxt);
2146 return -1;
2147
2148 case ESC:
2149 /* Allow users to bracketed-paste text into the string.
2150 Similar code is in search.c:_rl_nsearch_dispatch(). */
2151 if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1)))
2152 {
2153 if (_rl_read_bracketed_paste_prefix (c) == 1)
2154 rl_bracketed_paste_begin (1, c);
2155 else
2156 {
2157 c = rl_read_key (); /* get the ESC that got pushed back */
2158 _rl_insert_char (1, c);
2159 }
2160 }
2161 else
2162 _rl_insert_char (1, c);
2163 break;
2164
2165 case ' ':
2166 if ((cxt->flags & READSTR_NOSPACE) == 0)
2167 {
2168 _rl_insert_char (1, c);
2169 break;
2170 }
2171 /* FALLTHROUGH */
2172 case TAB:
2173 /* Perform completion if the caller has set a completion function. */
2174 n = (cxt->compfunc) ? (*cxt->compfunc) (cxt, c) : _rl_insert_char (1, c);
2175 if (n < 0)
2176 {
2177 _rl_readstr_restore (cxt);
2178 return -1;
2179 }
2180 break;
2181
2182 #if 0
2183 case CTRL('_'):
2184 rl_do_undo ();
2185 break;
2186 #endif
2187
2188 default:
2189 #if defined (HANDLE_MULTIBYTE)
2190 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2191 rl_insert_text (cxt->mb);
2192 else
2193 #endif
2194 _rl_insert_char (1, c);
2195 break;
2196 }
2197
2198 (*rl_redisplay_function) ();
2199 rl_deactivate_mark ();
2200 return 1;
2201 }
2202
2203 /* **************************************************************** */
2204 /* */
2205 /* Reading and Executing named commands */
2206 /* */
2207 /* **************************************************************** */
2208
2209 /* A completion generator for bindable readline command names. */
2210 static char *
2211 readcmd_completion_function (const char *text, int state)
2212 {
2213 static const char **cmdlist = NULL;
2214 static size_t lind, nlen;
2215 const char *cmdname;
2216
2217 if (state == 0)
2218 {
2219 if (cmdlist)
2220 free (cmdlist);
2221
2222 cmdlist = rl_funmap_names ();
2223 lind = 0;
2224 nlen = RL_STRLEN (text);
2225 }
2226 if (cmdlist == 0 || cmdlist[lind] == 0)
2227 return (char *)NULL;
2228
2229 while (cmdlist[lind])
2230 {
2231 cmdname = cmdlist[lind++];
2232 if (STREQN (text, cmdname, nlen))
2233 return (savestring (cmdname));
2234 }
2235 return ((char *)NULL);
2236 }
2237
2238 static void
2239 _rl_display_cmdname_matches (char **matches)
2240 {
2241 size_t len, max, i;
2242 int old;
2243
2244 old = rl_filename_completion_desired;
2245 rl_filename_completion_desired = 0;
2246
2247 /* There is more than one match. Find out how many there are,
2248 and find the maximum printed length of a single entry. */
2249 for (max = 0, i = 1; matches[i]; i++)
2250 {
2251 len = strlen (matches[i]);
2252
2253 if (len > max)
2254 max = len;
2255 }
2256 len = i - 1;
2257
2258 rl_display_match_list (matches, len, max);
2259 rl_filename_completion_desired = old;
2260
2261 rl_forced_update_display ();
2262 rl_display_fixed = 1;
2263 }
2264
2265 static int
2266 _rl_readcmd_complete (_rl_readstr_cxt *cxt, int c)
2267 {
2268 char **matches;
2269 char *prefix;
2270 size_t plen;
2271
2272 matches = rl_completion_matches (rl_line_buffer, readcmd_completion_function);
2273
2274 if (RL_SIG_RECEIVED())
2275 {
2276 _rl_free_match_list (matches);
2277 matches = 0;
2278 RL_CHECK_SIGNALS ();
2279 return -1;
2280 }
2281 else if (matches == 0)
2282 rl_ding ();
2283
2284 /* Whether or not there are multiple matches, we just want to append the
2285 new characters in matches[0]. We display possible matches if we didn't
2286 append anything. */
2287 if (matches)
2288 {
2289 prefix = matches[0];
2290 plen = strlen (prefix);
2291
2292 if (plen > rl_end)
2293 {
2294 size_t n;
2295 for (n = rl_end; n < plen && prefix[n]; n++)
2296 _rl_insert_char (1, prefix[n]);
2297 }
2298 else if (matches[1])
2299 _rl_display_cmdname_matches (matches);
2300 _rl_free_match_list (matches);
2301 }
2302
2303 return 0;
2304 }
2305
2306 /* Use the readstr functions to read a bindable command name using the
2307 line buffer, with completion. */
2308 static char *
2309 _rl_read_command_name ()
2310 {
2311 _rl_readstr_cxt *cxt;
2312 char *ret;
2313 int c, r;
2314
2315 cxt = _rl_readstr_init ('!', READSTR_NOSPACE);
2316 cxt->compfunc = _rl_readcmd_complete;
2317
2318 /* skip callback stuff for now */
2319 r = 0;
2320 while (1)
2321 {
2322 c = _rl_readstr_getchar (cxt);
2323
2324 if (c < 0)
2325 {
2326 _rl_readstr_restore (cxt);
2327 _rl_readstr_cleanup (cxt, r);
2328 return NULL;
2329 }
2330
2331 if (c == 0)
2332 break;
2333
2334 r = _rl_readstr_dispatch (cxt, c);
2335 if (r < 0)
2336 {
2337 _rl_readstr_cleanup (cxt, r);
2338 return NULL; /* dispatch function cleans up */
2339 }
2340 else if (r == 0)
2341 break;
2342 }
2343
2344 ret = savestring (rl_line_buffer);
2345
2346 /* Now restore the original line and perform one final redisplay. */
2347 _rl_readstr_restore (cxt);
2348 (*rl_redisplay_function) ();
2349
2350 /* And free up the context. */
2351 _rl_readstr_cleanup (cxt, r);
2352 return ret;
2353 }
2354
2355 /* Read a command name from the keyboard and execute it as if the bound key
2356 sequence had been entered. */
2357 int
2358 rl_execute_named_command (int count, int key)
2359 {
2360 char *command;
2361 rl_command_func_t *func;
2362 int r;
2363
2364 command = _rl_read_command_name ();
2365 if (command == 0 || *command == '\0')
2366 {
2367 free (command);
2368 return 1;
2369 }
2370 func = rl_named_function (command);
2371 free (command);
2372 if (func)
2373 {
2374 int prev, ostate;
2375
2376 prev = rl_dispatching;
2377 ostate = RL_ISSTATE (RL_STATE_DISPATCHING);
2378 rl_dispatching = 1;
2379 RL_SETSTATE (RL_STATE_DISPATCHING); /* make sure it's set */
2380 r = (*func) (count, key);
2381 if (ostate == 0)
2382 RL_UNSETSTATE (RL_STATE_DISPATCHING); /* unset it if it wasn't set */
2383 rl_dispatching = prev;
2384 }
2385 else
2386 {
2387 rl_ding ();
2388 r = 1;
2389 }
2390
2391 return r;
2392 }