Import readline 7.0 (patch 5)
[deliverable/binutils-gdb.git] / readline / text.c
CommitLineData
9255ee31
EZ
1/* text.c -- text handling commands for readline. */
2
775e241e 3/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
9255ee31 4
cc88a640
JK
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.
9255ee31 7
cc88a640
JK
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
9255ee31
EZ
11 (at your option) any later version.
12
cc88a640
JK
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
9255ee31
EZ
16 GNU General Public License for more details.
17
cc88a640
JK
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
9255ee31
EZ
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. */
62static int rl_change_case PARAMS((int, int));
63static int _rl_char_search PARAMS((int, int, int));
64
5bdf8622
DJ
65#if defined (READLINE_CALLBACKS)
66static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
67static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
68#endif
69
cc88a640
JK
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
775e241e
TT
74int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */
75
9255ee31
EZ
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. */
85int
86rl_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. */
123int
124rl_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
cc88a640 155 xfree (text);
9255ee31
EZ
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
174void
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
5bdf8622
DJ
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); */
9255ee31
EZ
187int
188_rl_replace_text (text, start, end)
189 const char *text;
190 int start, end;
191{
192 int n;
193
cc88a640 194 n = 0;
9255ee31 195 rl_begin_undo_group ();
cc88a640
JK
196 if (start <= end)
197 rl_delete_text (start, end + 1);
9255ee31 198 rl_point = start;
cc88a640
JK
199 if (*text)
200 n = rl_insert_text (text);
9255ee31
EZ
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. */
208void
209rl_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.
775e241e 245 The first is a count: the numeric arg passed to this command.
9255ee31
EZ
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. */
261int
262rl_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 {
cc88a640
JK
270 int end, lend;
271
272 end = rl_point + count;
9255ee31 273#if defined (VI_MODE)
cc88a640 274 lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
9255ee31 275#else
cc88a640 276 lend = rl_end;
9255ee31
EZ
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
cc88a640
JK
294int
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
9255ee31
EZ
319#if defined (HANDLE_MULTIBYTE)
320/* Move forward COUNT characters. */
321int
322rl_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 {
cc88a640
JK
335 if (rl_point == rl_end && EMACS_MODE())
336 {
337 rl_ding ();
338 return 0;
339 }
9255ee31 340
cc88a640 341 point = _rl_forward_char_internal (count);
9255ee31
EZ
342
343 if (rl_point == point)
344 rl_ding ();
345
346 rl_point = point;
9255ee31
EZ
347 }
348
349 return 0;
350}
351#else /* !HANDLE_MULTIBYTE */
352int
353rl_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. */
361int
362rl_forward (count, key)
363 int count, key;
364{
365 return (rl_forward_char (count, key));
366}
367
368/* Move backward COUNT bytes. */
369int
370rl_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. */
395int
396rl_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
428int
429rl_backward_char (count, key)
430 int count, key;
431{
432 return (rl_backward_byte (count, key));
433}
434#endif
435
436/* Backwards compatibility. */
437int
438rl_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. */
445int
446rl_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. */
454int
455rl_end_of_line (count, key)
456 int count, key;
457{
458 rl_point = rl_end;
459 return 0;
460}
461
5bdf8622 462/* Move forward a word. We do what Emacs does. Handles multibyte chars. */
9255ee31
EZ
463int
464rl_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. */
5bdf8622
DJ
479 c = _rl_char_value (rl_line_buffer, rl_point);
480
481 if (_rl_walphabetic (c) == 0)
9255ee31 482 {
5bdf8622
DJ
483 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
484 while (rl_point < rl_end)
9255ee31 485 {
5bdf8622
DJ
486 c = _rl_char_value (rl_line_buffer, rl_point);
487 if (_rl_walphabetic (c))
9255ee31 488 break;
5bdf8622 489 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
9255ee31
EZ
490 }
491 }
492
493 if (rl_point == rl_end)
494 return 0;
495
5bdf8622
DJ
496 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
497 while (rl_point < rl_end)
9255ee31 498 {
5bdf8622
DJ
499 c = _rl_char_value (rl_line_buffer, rl_point);
500 if (_rl_walphabetic (c) == 0)
9255ee31 501 break;
5bdf8622 502 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
9255ee31 503 }
5bdf8622 504
9255ee31
EZ
505 --count;
506 }
507
508 return 0;
509}
510
5bdf8622 511/* Move backward a word. We do what Emacs does. Handles multibyte chars. */
9255ee31
EZ
512int
513rl_backward_word (count, key)
514 int count, key;
515{
5bdf8622 516 int c, p;
9255ee31
EZ
517
518 if (count < 0)
519 return (rl_forward_word (-count, key));
520
521 while (count)
522 {
5bdf8622 523 if (rl_point == 0)
9255ee31
EZ
524 return 0;
525
526 /* Like rl_forward_word (), except that we look at the characters
527 just before point. */
528
5bdf8622
DJ
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)
9255ee31 533 {
5bdf8622
DJ
534 rl_point = p;
535 while (rl_point > 0)
9255ee31 536 {
5bdf8622
DJ
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))
9255ee31 540 break;
5bdf8622 541 rl_point = p;
9255ee31
EZ
542 }
543 }
544
545 while (rl_point)
546 {
5bdf8622
DJ
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)
9255ee31
EZ
550 break;
551 else
5bdf8622 552 rl_point = p;
9255ee31
EZ
553 }
554
555 --count;
556 }
557
558 return 0;
559}
560
561/* Clear the current line. Numeric argument to C-l does this. */
562int
563rl_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
775e241e 575 rl_redraw_prompt_last_line ();
9255ee31
EZ
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. */
584int
585rl_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
cc88a640
JK
601int
602rl_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
775e241e 613 return (ch < 0);
cc88a640
JK
614}
615
9255ee31
EZ
616int
617rl_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);
775e241e
TT
625 if (ch < 0)
626 return (1);
9255ee31
EZ
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
666static char pending_bytes[MB_LEN_MAX];
667static int pending_bytes_length = 0;
668static 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. */
674int
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. */
cc88a640 755 if (count > 1 && count <= TEXT_COUNT_MAX)
9255ee31
EZ
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);
cc88a640 778 xfree (string);
9255ee31
EZ
779
780 return 0;
781 }
782
cc88a640 783 if (count > TEXT_COUNT_MAX)
9255ee31
EZ
784 {
785 int decreaser;
786#if defined (HANDLE_MULTIBYTE)
cc88a640 787 string_size = incoming_length * TEXT_COUNT_MAX;
9255ee31
EZ
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 {
cc88a640 799 decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
9255ee31
EZ
800 string[decreaser*incoming_length] = '\0';
801 rl_insert_text (string);
802 count -= decreaser;
803 }
804
cc88a640 805 xfree (string);
9255ee31
EZ
806 incoming_length = 0;
807 stored_count = 0;
808#else /* !HANDLE_MULTIBYTE */
cc88a640 809 char str[TEXT_COUNT_MAX+1];
9255ee31 810
cc88a640 811 for (i = 0; i < TEXT_COUNT_MAX; i++)
9255ee31
EZ
812 str[i] = c;
813
814 while (count)
815 {
cc88a640 816 decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
9255ee31
EZ
817 str[decreaser] = '\0';
818 rl_insert_text (str);
819 count -= decreaser;
820 }
821#endif /* !HANDLE_MULTIBYTE */
822
823 return 0;
824 }
825
9255ee31
EZ
826 if (MB_CUR_MAX == 1 || rl_byte_oriented)
827 {
9255ee31
EZ
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
cc88a640
JK
831 them all. Don't do this if we're current reading input from
832 a macro. */
775e241e 833 if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ())
9255ee31
EZ
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 }
9255ee31 844 }
5bdf8622 845#if defined (HANDLE_MULTIBYTE)
9255ee31
EZ
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. */
859int
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
5bdf8622
DJ
873 rl_begin_undo_group ();
874
9255ee31
EZ
875 for (i = 0; i < count; i++)
876 {
9255ee31
EZ
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
5bdf8622
DJ
884 if (rl_point < rl_end)
885 rl_delete (1, c);
9255ee31
EZ
886 }
887
5bdf8622
DJ
888 rl_end_undo_group ();
889
9255ee31
EZ
890 return 0;
891}
892
893int
894rl_insert (count, c)
895 int count, c;
896{
775e241e
TT
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;
9255ee31
EZ
940}
941
942/* Insert the next typed character verbatim. */
5bdf8622
DJ
943static int
944_rl_insert_next (count)
945 int count;
9255ee31
EZ
946{
947 int c;
948
9255ee31
EZ
949 RL_SETSTATE(RL_STATE_MOREINPUT);
950 c = rl_read_key ();
951 RL_UNSETSTATE(RL_STATE_MOREINPUT);
952
cc88a640 953 if (c < 0)
775e241e
TT
954 return 1;
955
956 if (RL_ISSTATE (RL_STATE_MACRODEF))
957 _rl_add_macro_char (c);
cc88a640 958
9255ee31 959#if defined (HANDLE_SIGNALS)
5bdf8622
DJ
960 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
961 _rl_restore_tty_signals ();
9255ee31
EZ
962#endif
963
964 return (_rl_insert_char (count, c));
965}
966
5bdf8622
DJ
967#if defined (READLINE_CALLBACKS)
968static 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
984int
985rl_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
9255ee31
EZ
1006/* Insert a tab character. */
1007int
1008rl_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. */
1017int
1018rl_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 ();
5bdf8622
DJ
1032 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
1033 _rl_vi_reset_last ();
9255ee31
EZ
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
cc88a640 1042 if (_rl_echoing_p)
9255ee31
EZ
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. */
1051int
1052rl_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. */
1061int
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. */
5bdf8622
DJ
1091 if (rl_point < rl_end)
1092 {
1093 opoint = rl_point;
1094 _rl_insert_char (l, ' ');
1095 rl_point = opoint;
1096 }
9255ee31
EZ
1097
1098 rl_end_undo_group ();
1099
1100 return 0;
1101}
1102
1103/* Rubout the character behind point. */
1104int
1105rl_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 ();
775e241e 1114 return 1;
9255ee31
EZ
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
1123int
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 ();
775e241e 1137 return 1;
9255ee31
EZ
1138 }
1139
5bdf8622 1140 orig_point = rl_point;
9255ee31
EZ
1141 if (count > 1 || rl_explicit_arg)
1142 {
5bdf8622 1143 rl_backward_char (count, key);
9255ee31
EZ
1144 rl_kill_text (orig_point, rl_point);
1145 }
5bdf8622 1146 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
9255ee31 1147 {
5bdf8622
DJ
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. */
775e241e 1151 if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
9255ee31
EZ
1152 {
1153 int l;
1154 l = rl_character_len (c, rl_point);
1155 _rl_erase_at_end_of_line (l);
1156 }
1157 }
5bdf8622
DJ
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 }
9255ee31
EZ
1163
1164 return 0;
1165}
1166
1167/* Delete the character under the cursor. Given a numeric argument,
1168 kill that many characters instead. */
1169int
1170rl_delete (count, key)
1171 int count, key;
1172{
cc88a640
JK
1173 int xpoint;
1174
9255ee31
EZ
1175 if (count < 0)
1176 return (_rl_rubout_char (-count, key));
1177
1178 if (rl_point == rl_end)
1179 {
1180 rl_ding ();
775e241e 1181 return 1;
9255ee31
EZ
1182 }
1183
1184 if (count > 1 || rl_explicit_arg)
1185 {
cc88a640 1186 xpoint = rl_point;
9255ee31
EZ
1187 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1188 rl_forward_char (count, key);
1189 else
9255ee31
EZ
1190 rl_forward_byte (count, key);
1191
cc88a640
JK
1192 rl_kill_text (xpoint, rl_point);
1193 rl_point = xpoint;
9255ee31
EZ
1194 }
1195 else
1196 {
cc88a640
JK
1197 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1198 rl_delete_text (rl_point, xpoint);
9255ee31 1199 }
5bdf8622 1200 return 0;
9255ee31
EZ
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. */
1207int
1208rl_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. */
1218int
1219rl_delete_horizontal_space (count, ignore)
1220 int count, ignore;
1221{
cc88a640 1222 int start;
9255ee31
EZ
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 }
5bdf8622
DJ
1237
1238 if (rl_point < 0)
1239 rl_point = 0;
1240
9255ee31
EZ
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. */
1247int
1248rl_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. */
1263int
1264rl_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. */
1302int
1303rl_upcase_word (count, key)
1304 int count, key;
1305{
1306 return (rl_change_case (count, UpCase));
1307}
1308
1309/* Lowercase the word at point. */
1310int
1311rl_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. */
1318int
1319rl_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. */
1330static int
1331rl_change_case (count, op)
1332 int count, op;
1333{
5bdf8622
DJ
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];
cc88a640
JK
1339 int mlen;
1340 size_t m;
1341 mbstate_t mps;
5bdf8622 1342#endif
9255ee31
EZ
1343
1344 start = rl_point;
1345 rl_forward_word (count, 0);
1346 end = rl_point;
1347
5bdf8622
DJ
1348 if (op != UpCase && op != DownCase && op != CapCase)
1349 {
1350 rl_ding ();
775e241e 1351 return 1;
5bdf8622
DJ
1352 }
1353
9255ee31
EZ
1354 if (count < 0)
1355 SWAP (start, end);
1356
5bdf8622 1357#if defined (HANDLE_MULTIBYTE)
cc88a640 1358 memset (&mps, 0, sizeof (mbstate_t));
5bdf8622
DJ
1359#endif
1360
9255ee31
EZ
1361 /* We are going to modify some text, so let's prepare to undo it. */
1362 rl_modifying (start, end);
1363
5bdf8622
DJ
1364 inword = 0;
1365 while (start < end)
9255ee31 1366 {
5bdf8622
DJ
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);
9255ee31 1370
5bdf8622
DJ
1371 if (_rl_walphabetic (c) == 0)
1372 {
1373 inword = 0;
1374 start = next;
1375 continue;
1376 }
9255ee31 1377
5bdf8622
DJ
1378 if (op == CapCase)
1379 {
1380 nop = inword ? DownCase : UpCase;
1381 inword = 1;
9255ee31 1382 }
5bdf8622
DJ
1383 else
1384 nop = op;
775e241e 1385 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c))
5bdf8622
DJ
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 {
cc88a640
JK
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';
5bdf8622
DJ
1398 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1399 if (nwc != wc) /* just skip unchanged characters */
1400 {
cc88a640
JK
1401 mlen = wcrtomb (mb, nwc, &mps);
1402 if (mlen > 0)
1403 mb[mlen] = '\0';
5bdf8622 1404 /* Assume the same width */
cc88a640 1405 strncpy (rl_line_buffer + start, mb, mlen);
5bdf8622
DJ
1406 }
1407 }
1408#endif
1409
1410 start = next;
9255ee31 1411 }
5bdf8622 1412
9255ee31
EZ
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. */
1425int
1426rl_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;
775e241e 1451 return 1;
9255ee31
EZ
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 ();
cc88a640
JK
1478 xfree (word1);
1479 xfree (word2);
9255ee31
EZ
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. */
1486int
1487rl_transpose_chars (count, key)
1488 int count, key;
1489{
1490#if defined (HANDLE_MULTIBYTE)
1491 char *dummy;
5bdf8622 1492 int i;
9255ee31
EZ
1493#else
1494 char dummy[2];
1495#endif
5bdf8622 1496 int char_length, prev_point;
9255ee31
EZ
1497
1498 if (count == 0)
1499 return 0;
1500
1501 if (!rl_point || rl_end < 2)
1502 {
1503 rl_ding ();
775e241e 1504 return 1;
9255ee31
EZ
1505 }
1506
1507 rl_begin_undo_group ();
1508
1509 if (rl_point == rl_end)
1510 {
5bdf8622 1511 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
9255ee31
EZ
1512 count = 1;
1513 }
1514
9255ee31 1515 prev_point = rl_point;
5bdf8622 1516 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
9255ee31
EZ
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)
cc88a640 1538 xfree (dummy);
9255ee31
EZ
1539#endif
1540
1541 return 0;
1542}
1543
1544/* **************************************************************** */
1545/* */
1546/* Character Searching */
1547/* */
1548/* **************************************************************** */
1549
1550int
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
cc88a640 1566 if (dir == 0)
775e241e 1567 return 1;
cc88a640 1568
9255ee31
EZ
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 ();
775e241e 1576 return 1;
9255ee31
EZ
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)
1621static 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
cc88a640 1630 if (mb_len <= 0)
775e241e 1631 return 1;
cc88a640 1632
9255ee31
EZ
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 */
1639static 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
cc88a640 1649 if (c < 0)
775e241e 1650 return 1;
cc88a640 1651
9255ee31
EZ
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
5bdf8622
DJ
1659#if defined (READLINE_CALLBACKS)
1660static 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
9255ee31
EZ
1671int
1672rl_char_search (count, key)
1673 int count, key;
1674{
5bdf8622
DJ
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
9255ee31
EZ
1686 return (_rl_char_search (count, FFIND, BFIND));
1687}
1688
1689int
1690rl_backward_char_search (count, key)
1691 int count, key;
1692{
5bdf8622
DJ
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
9255ee31
EZ
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. */
1714int
1715_rl_set_mark_at_pos (position)
1716 int position;
1717{
1718 if (position > rl_end)
775e241e 1719 return 1;
9255ee31
EZ
1720
1721 rl_mark = position;
1722 return 0;
1723}
1724
1725/* A bindable command to set the mark. */
1726int
1727rl_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. */
1734int
1735rl_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 ();
775e241e 1744 return 1;
9255ee31
EZ
1745 }
1746 else
1747 SWAP (rl_point, rl_mark);
1748
1749 return 0;
1750}
This page took 0.821688 seconds and 4 git commands to generate.