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