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