f2bb22466c5ae3732f5d8f3e42730afc76216fd1
[deliverable/binutils-gdb.git] / readline / text.c
1 /* text.c -- text handling commands for readline. */
2
3 /* Copyright (C) 1987-2010 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_forced_update_display ();
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 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
626 switch (_rl_to_upper (ch))
627 {
628 case 'A':
629 rl_get_previous_history (count, ch);
630 break;
631
632 case 'B':
633 rl_get_next_history (count, ch);
634 break;
635
636 case 'C':
637 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
638 rl_forward_char (count, ch);
639 else
640 rl_forward_byte (count, ch);
641 break;
642
643 case 'D':
644 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
645 rl_backward_char (count, ch);
646 else
647 rl_backward_byte (count, ch);
648 break;
649
650 default:
651 rl_ding ();
652 }
653
654 return 0;
655 }
656
657 /* **************************************************************** */
658 /* */
659 /* Text commands */
660 /* */
661 /* **************************************************************** */
662
663 #ifdef HANDLE_MULTIBYTE
664 static char pending_bytes[MB_LEN_MAX];
665 static int pending_bytes_length = 0;
666 static mbstate_t ps = {0};
667 #endif
668
669 /* Insert the character C at the current location, moving point forward.
670 If C introduces a multibyte sequence, we read the whole sequence and
671 then insert the multibyte char into the line buffer. */
672 int
673 _rl_insert_char (count, c)
674 int count, c;
675 {
676 register int i;
677 char *string;
678 #ifdef HANDLE_MULTIBYTE
679 int string_size;
680 char incoming[MB_LEN_MAX + 1];
681 int incoming_length = 0;
682 mbstate_t ps_back;
683 static int stored_count = 0;
684 #endif
685
686 if (count <= 0)
687 return 0;
688
689 #if defined (HANDLE_MULTIBYTE)
690 if (MB_CUR_MAX == 1 || rl_byte_oriented)
691 {
692 incoming[0] = c;
693 incoming[1] = '\0';
694 incoming_length = 1;
695 }
696 else
697 {
698 wchar_t wc;
699 size_t ret;
700
701 if (stored_count <= 0)
702 stored_count = count;
703 else
704 count = stored_count;
705
706 ps_back = ps;
707 pending_bytes[pending_bytes_length++] = c;
708 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
709
710 if (ret == (size_t)-2)
711 {
712 /* Bytes too short to compose character, try to wait for next byte.
713 Restore the state of the byte sequence, because in this case the
714 effect of mbstate is undefined. */
715 ps = ps_back;
716 return 1;
717 }
718 else if (ret == (size_t)-1)
719 {
720 /* Invalid byte sequence for the current locale. Treat first byte
721 as a single character. */
722 incoming[0] = pending_bytes[0];
723 incoming[1] = '\0';
724 incoming_length = 1;
725 pending_bytes_length--;
726 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
727 /* Clear the state of the byte sequence, because in this case the
728 effect of mbstate is undefined. */
729 memset (&ps, 0, sizeof (mbstate_t));
730 }
731 else if (ret == (size_t)0)
732 {
733 incoming[0] = '\0';
734 incoming_length = 0;
735 pending_bytes_length--;
736 /* Clear the state of the byte sequence, because in this case the
737 effect of mbstate is undefined. */
738 memset (&ps, 0, sizeof (mbstate_t));
739 }
740 else
741 {
742 /* We successfully read a single multibyte character. */
743 memcpy (incoming, pending_bytes, pending_bytes_length);
744 incoming[pending_bytes_length] = '\0';
745 incoming_length = pending_bytes_length;
746 pending_bytes_length = 0;
747 }
748 }
749 #endif /* HANDLE_MULTIBYTE */
750
751 /* If we can optimize, then do it. But don't let people crash
752 readline because of extra large arguments. */
753 if (count > 1 && count <= TEXT_COUNT_MAX)
754 {
755 #if defined (HANDLE_MULTIBYTE)
756 string_size = count * incoming_length;
757 string = (char *)xmalloc (1 + string_size);
758
759 i = 0;
760 while (i < string_size)
761 {
762 strncpy (string + i, incoming, incoming_length);
763 i += incoming_length;
764 }
765 incoming_length = 0;
766 stored_count = 0;
767 #else /* !HANDLE_MULTIBYTE */
768 string = (char *)xmalloc (1 + count);
769
770 for (i = 0; i < count; i++)
771 string[i] = c;
772 #endif /* !HANDLE_MULTIBYTE */
773
774 string[i] = '\0';
775 rl_insert_text (string);
776 xfree (string);
777
778 return 0;
779 }
780
781 if (count > TEXT_COUNT_MAX)
782 {
783 int decreaser;
784 #if defined (HANDLE_MULTIBYTE)
785 string_size = incoming_length * TEXT_COUNT_MAX;
786 string = (char *)xmalloc (1 + string_size);
787
788 i = 0;
789 while (i < string_size)
790 {
791 strncpy (string + i, incoming, incoming_length);
792 i += incoming_length;
793 }
794
795 while (count)
796 {
797 decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
798 string[decreaser*incoming_length] = '\0';
799 rl_insert_text (string);
800 count -= decreaser;
801 }
802
803 xfree (string);
804 incoming_length = 0;
805 stored_count = 0;
806 #else /* !HANDLE_MULTIBYTE */
807 char str[TEXT_COUNT_MAX+1];
808
809 for (i = 0; i < TEXT_COUNT_MAX; i++)
810 str[i] = c;
811
812 while (count)
813 {
814 decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
815 str[decreaser] = '\0';
816 rl_insert_text (str);
817 count -= decreaser;
818 }
819 #endif /* !HANDLE_MULTIBYTE */
820
821 return 0;
822 }
823
824 if (MB_CUR_MAX == 1 || rl_byte_oriented)
825 {
826 /* We are inserting a single character.
827 If there is pending input, then make a string of all of the
828 pending characters that are bound to rl_insert, and insert
829 them all. Don't do this if we're current reading input from
830 a macro. */
831 if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ())
832 _rl_insert_typein (c);
833 else
834 {
835 /* Inserting a single character. */
836 char str[2];
837
838 str[1] = '\0';
839 str[0] = c;
840 rl_insert_text (str);
841 }
842 }
843 #if defined (HANDLE_MULTIBYTE)
844 else
845 {
846 rl_insert_text (incoming);
847 stored_count = 0;
848 }
849 #endif
850
851 return 0;
852 }
853
854 /* Overwrite the character at point (or next COUNT characters) with C.
855 If C introduces a multibyte character sequence, read the entire sequence
856 before starting the overwrite loop. */
857 int
858 _rl_overwrite_char (count, c)
859 int count, c;
860 {
861 int i;
862 #if defined (HANDLE_MULTIBYTE)
863 char mbkey[MB_LEN_MAX];
864 int k;
865
866 /* Read an entire multibyte character sequence to insert COUNT times. */
867 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
868 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
869 #endif
870
871 rl_begin_undo_group ();
872
873 for (i = 0; i < count; i++)
874 {
875 #if defined (HANDLE_MULTIBYTE)
876 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
877 rl_insert_text (mbkey);
878 else
879 #endif
880 _rl_insert_char (1, c);
881
882 if (rl_point < rl_end)
883 rl_delete (1, c);
884 }
885
886 rl_end_undo_group ();
887
888 return 0;
889 }
890
891 int
892 rl_insert (count, c)
893 int count, c;
894 {
895 int r, n, x;
896
897 r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (count, c) : _rl_overwrite_char (count, c);
898
899 /* XXX -- attempt to batch-insert pending input that maps to self-insert */
900 x = 0;
901 n = (unsigned short)-2;
902 while (_rl_optimize_typeahead &&
903 (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
904 _rl_pushed_input_available () == 0 &&
905 _rl_input_queued (0) &&
906 (n = rl_read_key ()) > 0 &&
907 _rl_keymap[(unsigned char)n].type == ISFUNC &&
908 _rl_keymap[(unsigned char)n].function == rl_insert)
909 {
910 r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (1, n) : _rl_overwrite_char (1, n);
911 /* _rl_insert_char keeps its own set of pending characters to compose a
912 complete multibyte character, and only returns 1 if it sees a character
913 that's part of a multibyte character but too short to complete one. We
914 can try to read another character in the hopes that we will get the
915 next one or just punt. Right now we try to read another character.
916 We don't want to call rl_insert_next if _rl_insert_char has already
917 stored the character in the pending_bytes array because that will
918 result in doubled input. */
919 n = (unsigned short)-2;
920 x++; /* count of bytes of typeahead read, currently unused */
921 if (r == 1) /* read partial multibyte character */
922 continue;
923 if (rl_done || r != 0)
924 break;
925 }
926
927 if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */
928 r = rl_execute_next (n);
929
930 return r;
931 }
932
933 /* Insert the next typed character verbatim. */
934 static int
935 _rl_insert_next (count)
936 int count;
937 {
938 int c;
939
940 RL_SETSTATE(RL_STATE_MOREINPUT);
941 c = rl_read_key ();
942 RL_UNSETSTATE(RL_STATE_MOREINPUT);
943
944 if (c < 0)
945 return 1;
946
947 if (RL_ISSTATE (RL_STATE_MACRODEF))
948 _rl_add_macro_char (c);
949
950 #if defined (HANDLE_SIGNALS)
951 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
952 _rl_restore_tty_signals ();
953 #endif
954
955 return (_rl_insert_char (count, c));
956 }
957
958 #if defined (READLINE_CALLBACKS)
959 static int
960 _rl_insert_next_callback (data)
961 _rl_callback_generic_arg *data;
962 {
963 int count;
964
965 count = data->count;
966
967 /* Deregister function, let rl_callback_read_char deallocate data */
968 _rl_callback_func = 0;
969 _rl_want_redisplay = 1;
970
971 return _rl_insert_next (count);
972 }
973 #endif
974
975 int
976 rl_quoted_insert (count, key)
977 int count, key;
978 {
979 /* Let's see...should the callback interface futz with signal handling? */
980 #if defined (HANDLE_SIGNALS)
981 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
982 _rl_disable_tty_signals ();
983 #endif
984
985 #if defined (READLINE_CALLBACKS)
986 if (RL_ISSTATE (RL_STATE_CALLBACK))
987 {
988 _rl_callback_data = _rl_callback_data_alloc (count);
989 _rl_callback_func = _rl_insert_next_callback;
990 return (0);
991 }
992 #endif
993
994 return _rl_insert_next (count);
995 }
996
997 /* Insert a tab character. */
998 int
999 rl_tab_insert (count, key)
1000 int count, key;
1001 {
1002 return (_rl_insert_char (count, '\t'));
1003 }
1004
1005 /* What to do when a NEWLINE is pressed. We accept the whole line.
1006 KEY is the key that invoked this command. I guess it could have
1007 meaning in the future. */
1008 int
1009 rl_newline (count, key)
1010 int count, key;
1011 {
1012 rl_done = 1;
1013
1014 if (_rl_history_preserve_point)
1015 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
1016
1017 RL_SETSTATE(RL_STATE_DONE);
1018
1019 #if defined (VI_MODE)
1020 if (rl_editing_mode == vi_mode)
1021 {
1022 _rl_vi_done_inserting ();
1023 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
1024 _rl_vi_reset_last ();
1025 }
1026 #endif /* VI_MODE */
1027
1028 /* If we've been asked to erase empty lines, suppress the final update,
1029 since _rl_update_final calls rl_crlf(). */
1030 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
1031 return 0;
1032
1033 if (_rl_echoing_p)
1034 _rl_update_final ();
1035 return 0;
1036 }
1037
1038 /* What to do for some uppercase characters, like meta characters,
1039 and some characters appearing in emacs_ctlx_keymap. This function
1040 is just a stub, you bind keys to it and the code in _rl_dispatch ()
1041 is special cased. */
1042 int
1043 rl_do_lowercase_version (ignore1, ignore2)
1044 int ignore1, ignore2;
1045 {
1046 return 0;
1047 }
1048
1049 /* This is different from what vi does, so the code's not shared. Emacs
1050 rubout in overwrite mode has one oddity: it replaces a control
1051 character that's displayed as two characters (^X) with two spaces. */
1052 int
1053 _rl_overwrite_rubout (count, key)
1054 int count, key;
1055 {
1056 int opoint;
1057 int i, l;
1058
1059 if (rl_point == 0)
1060 {
1061 rl_ding ();
1062 return 1;
1063 }
1064
1065 opoint = rl_point;
1066
1067 /* L == number of spaces to insert */
1068 for (i = l = 0; i < count; i++)
1069 {
1070 rl_backward_char (1, key);
1071 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
1072 }
1073
1074 rl_begin_undo_group ();
1075
1076 if (count > 1 || rl_explicit_arg)
1077 rl_kill_text (opoint, rl_point);
1078 else
1079 rl_delete_text (opoint, rl_point);
1080
1081 /* Emacs puts point at the beginning of the sequence of spaces. */
1082 if (rl_point < rl_end)
1083 {
1084 opoint = rl_point;
1085 _rl_insert_char (l, ' ');
1086 rl_point = opoint;
1087 }
1088
1089 rl_end_undo_group ();
1090
1091 return 0;
1092 }
1093
1094 /* Rubout the character behind point. */
1095 int
1096 rl_rubout (count, key)
1097 int count, key;
1098 {
1099 if (count < 0)
1100 return (rl_delete (-count, key));
1101
1102 if (!rl_point)
1103 {
1104 rl_ding ();
1105 return 1;
1106 }
1107
1108 if (rl_insert_mode == RL_IM_OVERWRITE)
1109 return (_rl_overwrite_rubout (count, key));
1110
1111 return (_rl_rubout_char (count, key));
1112 }
1113
1114 int
1115 _rl_rubout_char (count, key)
1116 int count, key;
1117 {
1118 int orig_point;
1119 unsigned char c;
1120
1121 /* Duplicated code because this is called from other parts of the library. */
1122 if (count < 0)
1123 return (rl_delete (-count, key));
1124
1125 if (rl_point == 0)
1126 {
1127 rl_ding ();
1128 return 1;
1129 }
1130
1131 orig_point = rl_point;
1132 if (count > 1 || rl_explicit_arg)
1133 {
1134 rl_backward_char (count, key);
1135 rl_kill_text (orig_point, rl_point);
1136 }
1137 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1138 {
1139 c = rl_line_buffer[--rl_point];
1140 rl_delete_text (rl_point, orig_point);
1141 /* The erase-at-end-of-line hack is of questionable merit now. */
1142 if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
1143 {
1144 int l;
1145 l = rl_character_len (c, rl_point);
1146 _rl_erase_at_end_of_line (l);
1147 }
1148 }
1149 else
1150 {
1151 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1152 rl_delete_text (rl_point, orig_point);
1153 }
1154
1155 return 0;
1156 }
1157
1158 /* Delete the character under the cursor. Given a numeric argument,
1159 kill that many characters instead. */
1160 int
1161 rl_delete (count, key)
1162 int count, key;
1163 {
1164 int xpoint;
1165
1166 if (count < 0)
1167 return (_rl_rubout_char (-count, key));
1168
1169 if (rl_point == rl_end)
1170 {
1171 rl_ding ();
1172 return 1;
1173 }
1174
1175 if (count > 1 || rl_explicit_arg)
1176 {
1177 xpoint = rl_point;
1178 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1179 rl_forward_char (count, key);
1180 else
1181 rl_forward_byte (count, key);
1182
1183 rl_kill_text (xpoint, rl_point);
1184 rl_point = xpoint;
1185 }
1186 else
1187 {
1188 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1189 rl_delete_text (rl_point, xpoint);
1190 }
1191 return 0;
1192 }
1193
1194 /* Delete the character under the cursor, unless the insertion
1195 point is at the end of the line, in which case the character
1196 behind the cursor is deleted. COUNT is obeyed and may be used
1197 to delete forward or backward that many characters. */
1198 int
1199 rl_rubout_or_delete (count, key)
1200 int count, key;
1201 {
1202 if (rl_end != 0 && rl_point == rl_end)
1203 return (_rl_rubout_char (count, key));
1204 else
1205 return (rl_delete (count, key));
1206 }
1207
1208 /* Delete all spaces and tabs around point. */
1209 int
1210 rl_delete_horizontal_space (count, ignore)
1211 int count, ignore;
1212 {
1213 int start;
1214
1215 while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1216 rl_point--;
1217
1218 start = rl_point;
1219
1220 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1221 rl_point++;
1222
1223 if (start != rl_point)
1224 {
1225 rl_delete_text (start, rl_point);
1226 rl_point = start;
1227 }
1228
1229 if (rl_point < 0)
1230 rl_point = 0;
1231
1232 return 0;
1233 }
1234
1235 /* Like the tcsh editing function delete-char-or-list. The eof character
1236 is caught before this is invoked, so this really does the same thing as
1237 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1238 int
1239 rl_delete_or_show_completions (count, key)
1240 int count, key;
1241 {
1242 if (rl_end != 0 && rl_point == rl_end)
1243 return (rl_possible_completions (count, key));
1244 else
1245 return (rl_delete (count, key));
1246 }
1247
1248 #ifndef RL_COMMENT_BEGIN_DEFAULT
1249 #define RL_COMMENT_BEGIN_DEFAULT "#"
1250 #endif
1251
1252 /* Turn the current line into a comment in shell history.
1253 A K*rn shell style function. */
1254 int
1255 rl_insert_comment (count, key)
1256 int count, key;
1257 {
1258 char *rl_comment_text;
1259 int rl_comment_len;
1260
1261 rl_beg_of_line (1, key);
1262 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1263
1264 if (rl_explicit_arg == 0)
1265 rl_insert_text (rl_comment_text);
1266 else
1267 {
1268 rl_comment_len = strlen (rl_comment_text);
1269 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1270 rl_delete_text (rl_point, rl_point + rl_comment_len);
1271 else
1272 rl_insert_text (rl_comment_text);
1273 }
1274
1275 (*rl_redisplay_function) ();
1276 rl_newline (1, '\n');
1277
1278 return (0);
1279 }
1280
1281 /* **************************************************************** */
1282 /* */
1283 /* Changing Case */
1284 /* */
1285 /* **************************************************************** */
1286
1287 /* The three kinds of things that we know how to do. */
1288 #define UpCase 1
1289 #define DownCase 2
1290 #define CapCase 3
1291
1292 /* Uppercase the word at point. */
1293 int
1294 rl_upcase_word (count, key)
1295 int count, key;
1296 {
1297 return (rl_change_case (count, UpCase));
1298 }
1299
1300 /* Lowercase the word at point. */
1301 int
1302 rl_downcase_word (count, key)
1303 int count, key;
1304 {
1305 return (rl_change_case (count, DownCase));
1306 }
1307
1308 /* Upcase the first letter, downcase the rest. */
1309 int
1310 rl_capitalize_word (count, key)
1311 int count, key;
1312 {
1313 return (rl_change_case (count, CapCase));
1314 }
1315
1316 /* The meaty function.
1317 Change the case of COUNT words, performing OP on them.
1318 OP is one of UpCase, DownCase, or CapCase.
1319 If a negative argument is given, leave point where it started,
1320 otherwise, leave it where it moves to. */
1321 static int
1322 rl_change_case (count, op)
1323 int count, op;
1324 {
1325 int start, next, end;
1326 int inword, c, nc, nop;
1327 #if defined (HANDLE_MULTIBYTE)
1328 wchar_t wc, nwc;
1329 char mb[MB_LEN_MAX+1];
1330 int mlen;
1331 size_t m;
1332 mbstate_t mps;
1333 #endif
1334
1335 start = rl_point;
1336 rl_forward_word (count, 0);
1337 end = rl_point;
1338
1339 if (op != UpCase && op != DownCase && op != CapCase)
1340 {
1341 rl_ding ();
1342 return 1;
1343 }
1344
1345 if (count < 0)
1346 SWAP (start, end);
1347
1348 #if defined (HANDLE_MULTIBYTE)
1349 memset (&mps, 0, sizeof (mbstate_t));
1350 #endif
1351
1352 /* We are going to modify some text, so let's prepare to undo it. */
1353 rl_modifying (start, end);
1354
1355 inword = 0;
1356 while (start < end)
1357 {
1358 c = _rl_char_value (rl_line_buffer, start);
1359 /* This assumes that the upper and lower case versions are the same width. */
1360 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1361
1362 if (_rl_walphabetic (c) == 0)
1363 {
1364 inword = 0;
1365 start = next;
1366 continue;
1367 }
1368
1369 if (op == CapCase)
1370 {
1371 nop = inword ? DownCase : UpCase;
1372 inword = 1;
1373 }
1374 else
1375 nop = op;
1376 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c))
1377 {
1378 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
1379 rl_line_buffer[start] = nc;
1380 }
1381 #if defined (HANDLE_MULTIBYTE)
1382 else
1383 {
1384 m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
1385 if (MB_INVALIDCH (m))
1386 wc = (wchar_t)rl_line_buffer[start];
1387 else if (MB_NULLWCH (m))
1388 wc = L'\0';
1389 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1390 if (nwc != wc) /* just skip unchanged characters */
1391 {
1392 mlen = wcrtomb (mb, nwc, &mps);
1393 if (mlen > 0)
1394 mb[mlen] = '\0';
1395 /* Assume the same width */
1396 strncpy (rl_line_buffer + start, mb, mlen);
1397 }
1398 }
1399 #endif
1400
1401 start = next;
1402 }
1403
1404 rl_point = end;
1405 return 0;
1406 }
1407
1408 /* **************************************************************** */
1409 /* */
1410 /* Transposition */
1411 /* */
1412 /* **************************************************************** */
1413
1414 /* Transpose the words at point. If point is at the end of the line,
1415 transpose the two words before point. */
1416 int
1417 rl_transpose_words (count, key)
1418 int count, key;
1419 {
1420 char *word1, *word2;
1421 int w1_beg, w1_end, w2_beg, w2_end;
1422 int orig_point = rl_point;
1423
1424 if (!count)
1425 return 0;
1426
1427 /* Find the two words. */
1428 rl_forward_word (count, key);
1429 w2_end = rl_point;
1430 rl_backward_word (1, key);
1431 w2_beg = rl_point;
1432 rl_backward_word (count, key);
1433 w1_beg = rl_point;
1434 rl_forward_word (1, key);
1435 w1_end = rl_point;
1436
1437 /* Do some check to make sure that there really are two words. */
1438 if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1439 {
1440 rl_ding ();
1441 rl_point = orig_point;
1442 return 1;
1443 }
1444
1445 /* Get the text of the words. */
1446 word1 = rl_copy_text (w1_beg, w1_end);
1447 word2 = rl_copy_text (w2_beg, w2_end);
1448
1449 /* We are about to do many insertions and deletions. Remember them
1450 as one operation. */
1451 rl_begin_undo_group ();
1452
1453 /* Do the stuff at word2 first, so that we don't have to worry
1454 about word1 moving. */
1455 rl_point = w2_beg;
1456 rl_delete_text (w2_beg, w2_end);
1457 rl_insert_text (word1);
1458
1459 rl_point = w1_beg;
1460 rl_delete_text (w1_beg, w1_end);
1461 rl_insert_text (word2);
1462
1463 /* This is exactly correct since the text before this point has not
1464 changed in length. */
1465 rl_point = w2_end;
1466
1467 /* I think that does it. */
1468 rl_end_undo_group ();
1469 xfree (word1);
1470 xfree (word2);
1471
1472 return 0;
1473 }
1474
1475 /* Transpose the characters at point. If point is at the end of the line,
1476 then transpose the characters before point. */
1477 int
1478 rl_transpose_chars (count, key)
1479 int count, key;
1480 {
1481 #if defined (HANDLE_MULTIBYTE)
1482 char *dummy;
1483 int i;
1484 #else
1485 char dummy[2];
1486 #endif
1487 int char_length, prev_point;
1488
1489 if (count == 0)
1490 return 0;
1491
1492 if (!rl_point || rl_end < 2)
1493 {
1494 rl_ding ();
1495 return 1;
1496 }
1497
1498 rl_begin_undo_group ();
1499
1500 if (rl_point == rl_end)
1501 {
1502 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1503 count = 1;
1504 }
1505
1506 prev_point = rl_point;
1507 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1508
1509 #if defined (HANDLE_MULTIBYTE)
1510 char_length = prev_point - rl_point;
1511 dummy = (char *)xmalloc (char_length + 1);
1512 for (i = 0; i < char_length; i++)
1513 dummy[i] = rl_line_buffer[rl_point + i];
1514 dummy[i] = '\0';
1515 #else
1516 dummy[0] = rl_line_buffer[rl_point];
1517 dummy[char_length = 1] = '\0';
1518 #endif
1519
1520 rl_delete_text (rl_point, rl_point + char_length);
1521
1522 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1523
1524 _rl_fix_point (0);
1525 rl_insert_text (dummy);
1526 rl_end_undo_group ();
1527
1528 #if defined (HANDLE_MULTIBYTE)
1529 xfree (dummy);
1530 #endif
1531
1532 return 0;
1533 }
1534
1535 /* **************************************************************** */
1536 /* */
1537 /* Character Searching */
1538 /* */
1539 /* **************************************************************** */
1540
1541 int
1542 #if defined (HANDLE_MULTIBYTE)
1543 _rl_char_search_internal (count, dir, smbchar, len)
1544 int count, dir;
1545 char *smbchar;
1546 int len;
1547 #else
1548 _rl_char_search_internal (count, dir, schar)
1549 int count, dir, schar;
1550 #endif
1551 {
1552 int pos, inc;
1553 #if defined (HANDLE_MULTIBYTE)
1554 int prepos;
1555 #endif
1556
1557 if (dir == 0)
1558 return 1;
1559
1560 pos = rl_point;
1561 inc = (dir < 0) ? -1 : 1;
1562 while (count)
1563 {
1564 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1565 {
1566 rl_ding ();
1567 return 1;
1568 }
1569
1570 #if defined (HANDLE_MULTIBYTE)
1571 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1572 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1573 #else
1574 pos += inc;
1575 #endif
1576 do
1577 {
1578 #if defined (HANDLE_MULTIBYTE)
1579 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1580 #else
1581 if (rl_line_buffer[pos] == schar)
1582 #endif
1583 {
1584 count--;
1585 if (dir < 0)
1586 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1587 : pos;
1588 else
1589 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1590 : pos;
1591 break;
1592 }
1593 #if defined (HANDLE_MULTIBYTE)
1594 prepos = pos;
1595 #endif
1596 }
1597 #if defined (HANDLE_MULTIBYTE)
1598 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1599 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1600 #else
1601 while ((dir < 0) ? pos-- : ++pos < rl_end);
1602 #endif
1603 }
1604 return (0);
1605 }
1606
1607 /* Search COUNT times for a character read from the current input stream.
1608 FDIR is the direction to search if COUNT is non-negative; otherwise
1609 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1610 that there are two separate versions of this function. */
1611 #if defined (HANDLE_MULTIBYTE)
1612 static int
1613 _rl_char_search (count, fdir, bdir)
1614 int count, fdir, bdir;
1615 {
1616 char mbchar[MB_LEN_MAX];
1617 int mb_len;
1618
1619 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1620
1621 if (mb_len <= 0)
1622 return 1;
1623
1624 if (count < 0)
1625 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1626 else
1627 return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1628 }
1629 #else /* !HANDLE_MULTIBYTE */
1630 static int
1631 _rl_char_search (count, fdir, bdir)
1632 int count, fdir, bdir;
1633 {
1634 int c;
1635
1636 RL_SETSTATE(RL_STATE_MOREINPUT);
1637 c = rl_read_key ();
1638 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1639
1640 if (c < 0)
1641 return 1;
1642
1643 if (count < 0)
1644 return (_rl_char_search_internal (-count, bdir, c));
1645 else
1646 return (_rl_char_search_internal (count, fdir, c));
1647 }
1648 #endif /* !HANDLE_MULTIBYTE */
1649
1650 #if defined (READLINE_CALLBACKS)
1651 static int
1652 _rl_char_search_callback (data)
1653 _rl_callback_generic_arg *data;
1654 {
1655 _rl_callback_func = 0;
1656 _rl_want_redisplay = 1;
1657
1658 return (_rl_char_search (data->count, data->i1, data->i2));
1659 }
1660 #endif
1661
1662 int
1663 rl_char_search (count, key)
1664 int count, key;
1665 {
1666 #if defined (READLINE_CALLBACKS)
1667 if (RL_ISSTATE (RL_STATE_CALLBACK))
1668 {
1669 _rl_callback_data = _rl_callback_data_alloc (count);
1670 _rl_callback_data->i1 = FFIND;
1671 _rl_callback_data->i2 = BFIND;
1672 _rl_callback_func = _rl_char_search_callback;
1673 return (0);
1674 }
1675 #endif
1676
1677 return (_rl_char_search (count, FFIND, BFIND));
1678 }
1679
1680 int
1681 rl_backward_char_search (count, key)
1682 int count, key;
1683 {
1684 #if defined (READLINE_CALLBACKS)
1685 if (RL_ISSTATE (RL_STATE_CALLBACK))
1686 {
1687 _rl_callback_data = _rl_callback_data_alloc (count);
1688 _rl_callback_data->i1 = BFIND;
1689 _rl_callback_data->i2 = FFIND;
1690 _rl_callback_func = _rl_char_search_callback;
1691 return (0);
1692 }
1693 #endif
1694
1695 return (_rl_char_search (count, BFIND, FFIND));
1696 }
1697
1698 /* **************************************************************** */
1699 /* */
1700 /* The Mark and the Region. */
1701 /* */
1702 /* **************************************************************** */
1703
1704 /* Set the mark at POSITION. */
1705 int
1706 _rl_set_mark_at_pos (position)
1707 int position;
1708 {
1709 if (position > rl_end)
1710 return 1;
1711
1712 rl_mark = position;
1713 return 0;
1714 }
1715
1716 /* A bindable command to set the mark. */
1717 int
1718 rl_set_mark (count, key)
1719 int count, key;
1720 {
1721 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1722 }
1723
1724 /* Exchange the position of mark and point. */
1725 int
1726 rl_exchange_point_and_mark (count, key)
1727 int count, key;
1728 {
1729 if (rl_mark > rl_end)
1730 rl_mark = -1;
1731
1732 if (rl_mark == -1)
1733 {
1734 rl_ding ();
1735 return 1;
1736 }
1737 else
1738 SWAP (rl_point, rl_mark);
1739
1740 return 0;
1741 }
This page took 0.094697 seconds and 3 git commands to generate.