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