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 (c < 0)
861    return -1;
862
863#if defined (HANDLE_SIGNALS)
864  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
865    _rl_restore_tty_signals ();
866#endif
867
868  return (_rl_insert_char (count, c));
869}
870
871#if defined (READLINE_CALLBACKS)
872static int
873_rl_insert_next_callback (data)
874     _rl_callback_generic_arg *data;
875{
876  int count;
877
878  count = data->count;
879
880  /* Deregister function, let rl_callback_read_char deallocate data */
881  _rl_callback_func = 0;
882  _rl_want_redisplay = 1;
883
884  return _rl_insert_next (count);
885}
886#endif
887
888int
889rl_quoted_insert (count, key)
890     int count, key;
891{
892  /* Let's see...should the callback interface futz with signal handling? */
893#if defined (HANDLE_SIGNALS)
894  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
895    _rl_disable_tty_signals ();
896#endif
897
898#if defined (READLINE_CALLBACKS)
899  if (RL_ISSTATE (RL_STATE_CALLBACK))
900    {
901      _rl_callback_data = _rl_callback_data_alloc (count);
902      _rl_callback_func = _rl_insert_next_callback;
903      return (0);
904    }
905#endif
906
907  return _rl_insert_next (count);
908}
909
910/* Insert a tab character. */
911int
912rl_tab_insert (count, key)
913     int count, key;
914{
915  return (_rl_insert_char (count, '\t'));
916}
917
918/* What to do when a NEWLINE is pressed.  We accept the whole line.
919   KEY is the key that invoked this command.  I guess it could have
920   meaning in the future. */
921int
922rl_newline (count, key)
923     int count, key;
924{
925  rl_done = 1;
926
927  if (_rl_history_preserve_point)
928    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
929
930  RL_SETSTATE(RL_STATE_DONE);
931
932#if defined (VI_MODE)
933  if (rl_editing_mode == vi_mode)
934    {
935      _rl_vi_done_inserting ();
936      if (_rl_vi_textmod_command (_rl_vi_last_command) == 0)	/* XXX */
937	_rl_vi_reset_last ();
938    }
939#endif /* VI_MODE */
940
941  /* If we've been asked to erase empty lines, suppress the final update,
942     since _rl_update_final calls rl_crlf(). */
943  if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
944    return 0;
945
946  if (readline_echoing_p)
947    _rl_update_final ();
948  return 0;
949}
950
951/* What to do for some uppercase characters, like meta characters,
952   and some characters appearing in emacs_ctlx_keymap.  This function
953   is just a stub, you bind keys to it and the code in _rl_dispatch ()
954   is special cased. */
955int
956rl_do_lowercase_version (ignore1, ignore2)
957     int ignore1, ignore2;
958{
959  return 0;
960}
961
962/* This is different from what vi does, so the code's not shared.  Emacs
963   rubout in overwrite mode has one oddity:  it replaces a control
964   character that's displayed as two characters (^X) with two spaces. */
965int
966_rl_overwrite_rubout (count, key)
967     int count, key;
968{
969  int opoint;
970  int i, l;
971
972  if (rl_point == 0)
973    {
974      rl_ding ();
975      return 1;
976    }
977
978  opoint = rl_point;
979
980  /* L == number of spaces to insert */
981  for (i = l = 0; i < count; i++)
982    {
983      rl_backward_char (1, key);
984      l += rl_character_len (rl_line_buffer[rl_point], rl_point);	/* not exactly right */
985    }
986
987  rl_begin_undo_group ();
988
989  if (count > 1 || rl_explicit_arg)
990    rl_kill_text (opoint, rl_point);
991  else
992    rl_delete_text (opoint, rl_point);
993
994  /* Emacs puts point at the beginning of the sequence of spaces. */
995  if (rl_point < rl_end)
996    {
997      opoint = rl_point;
998      _rl_insert_char (l, ' ');
999      rl_point = opoint;
1000    }
1001
1002  rl_end_undo_group ();
1003
1004  return 0;
1005}
1006
1007/* Rubout the character behind point. */
1008int
1009rl_rubout (count, key)
1010     int count, key;
1011{
1012  if (count < 0)
1013    return (rl_delete (-count, key));
1014
1015  if (!rl_point)
1016    {
1017      rl_ding ();
1018      return -1;
1019    }
1020
1021  if (rl_insert_mode == RL_IM_OVERWRITE)
1022    return (_rl_overwrite_rubout (count, key));
1023
1024  return (_rl_rubout_char (count, key));
1025}
1026
1027int
1028_rl_rubout_char (count, key)
1029     int count, key;
1030{
1031  int orig_point;
1032  unsigned char c;
1033
1034  /* Duplicated code because this is called from other parts of the library. */
1035  if (count < 0)
1036    return (rl_delete (-count, key));
1037
1038  if (rl_point == 0)
1039    {
1040      rl_ding ();
1041      return -1;
1042    }
1043
1044  orig_point = rl_point;
1045  if (count > 1 || rl_explicit_arg)
1046    {
1047      rl_backward_char (count, key);
1048      rl_kill_text (orig_point, rl_point);
1049    }
1050  else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1051    {
1052      c = rl_line_buffer[--rl_point];
1053      rl_delete_text (rl_point, orig_point);
1054      /* The erase-at-end-of-line hack is of questionable merit now. */
1055      if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
1056	{
1057	  int l;
1058	  l = rl_character_len (c, rl_point);
1059	  _rl_erase_at_end_of_line (l);
1060	}
1061    }
1062  else
1063    {
1064      rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1065      rl_delete_text (rl_point, orig_point);
1066    }
1067
1068  return 0;
1069}
1070
1071/* Delete the character under the cursor.  Given a numeric argument,
1072   kill that many characters instead. */
1073int
1074rl_delete (count, key)
1075     int count, key;
1076{
1077  int xpoint;
1078
1079  if (count < 0)
1080    return (_rl_rubout_char (-count, key));
1081
1082  if (rl_point == rl_end)
1083    {
1084      rl_ding ();
1085      return -1;
1086    }
1087
1088  if (count > 1 || rl_explicit_arg)
1089    {
1090      xpoint = rl_point;
1091      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1092	rl_forward_char (count, key);
1093      else
1094	rl_forward_byte (count, key);
1095
1096      rl_kill_text (xpoint, rl_point);
1097      rl_point = xpoint;
1098    }
1099  else
1100    {
1101      xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1102      rl_delete_text (rl_point, xpoint);
1103    }
1104  return 0;
1105}
1106
1107/* Delete the character under the cursor, unless the insertion
1108   point is at the end of the line, in which case the character
1109   behind the cursor is deleted.  COUNT is obeyed and may be used
1110   to delete forward or backward that many characters. */
1111int
1112rl_rubout_or_delete (count, key)
1113     int count, key;
1114{
1115  if (rl_end != 0 && rl_point == rl_end)
1116    return (_rl_rubout_char (count, key));
1117  else
1118    return (rl_delete (count, key));
1119}
1120
1121/* Delete all spaces and tabs around point. */
1122int
1123rl_delete_horizontal_space (count, ignore)
1124     int count, ignore;
1125{
1126  int start = rl_point;
1127
1128  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1129    rl_point--;
1130
1131  start = rl_point;
1132
1133  while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1134    rl_point++;
1135
1136  if (start != rl_point)
1137    {
1138      rl_delete_text (start, rl_point);
1139      rl_point = start;
1140    }
1141
1142  if (rl_point < 0)
1143    rl_point = 0;
1144
1145  return 0;
1146}
1147
1148/* Like the tcsh editing function delete-char-or-list.  The eof character
1149   is caught before this is invoked, so this really does the same thing as
1150   delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1151int
1152rl_delete_or_show_completions (count, key)
1153     int count, key;
1154{
1155  if (rl_end != 0 && rl_point == rl_end)
1156    return (rl_possible_completions (count, key));
1157  else
1158    return (rl_delete (count, key));
1159}
1160
1161#ifndef RL_COMMENT_BEGIN_DEFAULT
1162#define RL_COMMENT_BEGIN_DEFAULT "#"
1163#endif
1164
1165/* Turn the current line into a comment in shell history.
1166   A K*rn shell style function. */
1167int
1168rl_insert_comment (count, key)
1169     int count, key;
1170{
1171  char *rl_comment_text;
1172  int rl_comment_len;
1173
1174  rl_beg_of_line (1, key);
1175  rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1176
1177  if (rl_explicit_arg == 0)
1178    rl_insert_text (rl_comment_text);
1179  else
1180    {
1181      rl_comment_len = strlen (rl_comment_text);
1182      if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1183	rl_delete_text (rl_point, rl_point + rl_comment_len);
1184      else
1185	rl_insert_text (rl_comment_text);
1186    }
1187
1188  (*rl_redisplay_function) ();
1189  rl_newline (1, '\n');
1190
1191  return (0);
1192}
1193
1194/* **************************************************************** */
1195/*								    */
1196/*			Changing Case				    */
1197/*								    */
1198/* **************************************************************** */
1199
1200/* The three kinds of things that we know how to do. */
1201#define UpCase 1
1202#define DownCase 2
1203#define CapCase 3
1204
1205/* Uppercase the word at point. */
1206int
1207rl_upcase_word (count, key)
1208     int count, key;
1209{
1210  return (rl_change_case (count, UpCase));
1211}
1212
1213/* Lowercase the word at point. */
1214int
1215rl_downcase_word (count, key)
1216     int count, key;
1217{
1218  return (rl_change_case (count, DownCase));
1219}
1220
1221/* Upcase the first letter, downcase the rest. */
1222int
1223rl_capitalize_word (count, key)
1224     int count, key;
1225{
1226 return (rl_change_case (count, CapCase));
1227}
1228
1229/* The meaty function.
1230   Change the case of COUNT words, performing OP on them.
1231   OP is one of UpCase, DownCase, or CapCase.
1232   If a negative argument is given, leave point where it started,
1233   otherwise, leave it where it moves to. */
1234static int
1235rl_change_case (count, op)
1236     int count, op;
1237{
1238  int start, next, end;
1239  int inword, c, nc, nop;
1240#if defined (HANDLE_MULTIBYTE)
1241  wchar_t wc, nwc;
1242  char mb[MB_LEN_MAX+1];
1243  int mlen;
1244  mbstate_t mps;
1245#endif
1246
1247  start = rl_point;
1248  rl_forward_word (count, 0);
1249  end = rl_point;
1250
1251  if (op != UpCase && op != DownCase && op != CapCase)
1252    {
1253      rl_ding ();
1254      return -1;
1255    }
1256
1257  if (count < 0)
1258    SWAP (start, end);
1259
1260#if defined (HANDLE_MULTIBYTE)
1261  memset (&mps, 0, sizeof (mbstate_t));
1262#endif
1263
1264  /* We are going to modify some text, so let's prepare to undo it. */
1265  rl_modifying (start, end);
1266
1267  inword = 0;
1268  while (start < end)
1269    {
1270      c = _rl_char_value (rl_line_buffer, start);
1271      /*  This assumes that the upper and lower case versions are the same width. */
1272      next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1273
1274      if (_rl_walphabetic (c) == 0)
1275	{
1276	  inword = 0;
1277	  start = next;
1278	  continue;
1279	}
1280
1281      if (op == CapCase)
1282	{
1283	  nop = inword ? DownCase : UpCase;
1284	  inword = 1;
1285	}
1286      else
1287	nop = op;
1288      if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
1289	{
1290	  nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
1291	  rl_line_buffer[start] = nc;
1292	}
1293#if defined (HANDLE_MULTIBYTE)
1294      else
1295	{
1296	  mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
1297	  nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1298	  if  (nwc != wc)	/*  just skip unchanged characters */
1299	    {
1300	      mlen = wcrtomb (mb, nwc, &mps);
1301	      if (mlen > 0)
1302		mb[mlen] = '\0';
1303	      /* Assume the same width */
1304	      strncpy (rl_line_buffer + start, mb, mlen);
1305	    }
1306	}
1307#endif
1308
1309      start = next;
1310    }
1311
1312  rl_point = end;
1313  return 0;
1314}
1315
1316/* **************************************************************** */
1317/*								    */
1318/*			Transposition				    */
1319/*								    */
1320/* **************************************************************** */
1321
1322/* Transpose the words at point.  If point is at the end of the line,
1323   transpose the two words before point. */
1324int
1325rl_transpose_words (count, key)
1326     int count, key;
1327{
1328  char *word1, *word2;
1329  int w1_beg, w1_end, w2_beg, w2_end;
1330  int orig_point = rl_point;
1331
1332  if (!count)
1333    return 0;
1334
1335  /* Find the two words. */
1336  rl_forward_word (count, key);
1337  w2_end = rl_point;
1338  rl_backward_word (1, key);
1339  w2_beg = rl_point;
1340  rl_backward_word (count, key);
1341  w1_beg = rl_point;
1342  rl_forward_word (1, key);
1343  w1_end = rl_point;
1344
1345  /* Do some check to make sure that there really are two words. */
1346  if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1347    {
1348      rl_ding ();
1349      rl_point = orig_point;
1350      return -1;
1351    }
1352
1353  /* Get the text of the words. */
1354  word1 = rl_copy_text (w1_beg, w1_end);
1355  word2 = rl_copy_text (w2_beg, w2_end);
1356
1357  /* We are about to do many insertions and deletions.  Remember them
1358     as one operation. */
1359  rl_begin_undo_group ();
1360
1361  /* Do the stuff at word2 first, so that we don't have to worry
1362     about word1 moving. */
1363  rl_point = w2_beg;
1364  rl_delete_text (w2_beg, w2_end);
1365  rl_insert_text (word1);
1366
1367  rl_point = w1_beg;
1368  rl_delete_text (w1_beg, w1_end);
1369  rl_insert_text (word2);
1370
1371  /* This is exactly correct since the text before this point has not
1372     changed in length. */
1373  rl_point = w2_end;
1374
1375  /* I think that does it. */
1376  rl_end_undo_group ();
1377  free (word1);
1378  free (word2);
1379
1380  return 0;
1381}
1382
1383/* Transpose the characters at point.  If point is at the end of the line,
1384   then transpose the characters before point. */
1385int
1386rl_transpose_chars (count, key)
1387     int count, key;
1388{
1389#if defined (HANDLE_MULTIBYTE)
1390  char *dummy;
1391  int i;
1392#else
1393  char dummy[2];
1394#endif
1395  int char_length, prev_point;
1396
1397  if (count == 0)
1398    return 0;
1399
1400  if (!rl_point || rl_end < 2)
1401    {
1402      rl_ding ();
1403      return -1;
1404    }
1405
1406  rl_begin_undo_group ();
1407
1408  if (rl_point == rl_end)
1409    {
1410      rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1411      count = 1;
1412    }
1413
1414  prev_point = rl_point;
1415  rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1416
1417#if defined (HANDLE_MULTIBYTE)
1418  char_length = prev_point - rl_point;
1419  dummy = (char *)xmalloc (char_length + 1);
1420  for (i = 0; i < char_length; i++)
1421    dummy[i] = rl_line_buffer[rl_point + i];
1422  dummy[i] = '\0';
1423#else
1424  dummy[0] = rl_line_buffer[rl_point];
1425  dummy[char_length = 1] = '\0';
1426#endif
1427
1428  rl_delete_text (rl_point, rl_point + char_length);
1429
1430  rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1431
1432  _rl_fix_point (0);
1433  rl_insert_text (dummy);
1434  rl_end_undo_group ();
1435
1436#if defined (HANDLE_MULTIBYTE)
1437  free (dummy);
1438#endif
1439
1440  return 0;
1441}
1442
1443/* **************************************************************** */
1444/*								    */
1445/*			Character Searching			    */
1446/*								    */
1447/* **************************************************************** */
1448
1449int
1450#if defined (HANDLE_MULTIBYTE)
1451_rl_char_search_internal (count, dir, smbchar, len)
1452     int count, dir;
1453     char *smbchar;
1454     int len;
1455#else
1456_rl_char_search_internal (count, dir, schar)
1457     int count, dir, schar;
1458#endif
1459{
1460  int pos, inc;
1461#if defined (HANDLE_MULTIBYTE)
1462  int prepos;
1463#endif
1464
1465  pos = rl_point;
1466  inc = (dir < 0) ? -1 : 1;
1467  while (count)
1468    {
1469      if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1470	{
1471	  rl_ding ();
1472	  return -1;
1473	}
1474
1475#if defined (HANDLE_MULTIBYTE)
1476      pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1477		      : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1478#else
1479      pos += inc;
1480#endif
1481      do
1482	{
1483#if defined (HANDLE_MULTIBYTE)
1484	  if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1485#else
1486	  if (rl_line_buffer[pos] == schar)
1487#endif
1488	    {
1489	      count--;
1490	      if (dir < 0)
1491	        rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1492					: pos;
1493	      else
1494		rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1495					: pos;
1496	      break;
1497	    }
1498#if defined (HANDLE_MULTIBYTE)
1499	  prepos = pos;
1500#endif
1501	}
1502#if defined (HANDLE_MULTIBYTE)
1503      while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1504		       : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1505#else
1506      while ((dir < 0) ? pos-- : ++pos < rl_end);
1507#endif
1508    }
1509  return (0);
1510}
1511
1512/* Search COUNT times for a character read from the current input stream.
1513   FDIR is the direction to search if COUNT is non-negative; otherwise
1514   the search goes in BDIR.  So much is dependent on HANDLE_MULTIBYTE
1515   that there are two separate versions of this function. */
1516#if defined (HANDLE_MULTIBYTE)
1517static int
1518_rl_char_search (count, fdir, bdir)
1519     int count, fdir, bdir;
1520{
1521  char mbchar[MB_LEN_MAX];
1522  int mb_len;
1523
1524  mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1525
1526  if (mb_len <= 0)
1527    return -1;
1528
1529  if (count < 0)
1530    return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1531  else
1532    return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1533}
1534#else /* !HANDLE_MULTIBYTE */
1535static int
1536_rl_char_search (count, fdir, bdir)
1537     int count, fdir, bdir;
1538{
1539  int c;
1540
1541  RL_SETSTATE(RL_STATE_MOREINPUT);
1542  c = rl_read_key ();
1543  RL_UNSETSTATE(RL_STATE_MOREINPUT);
1544
1545  if (c < 0)
1546    return -1;
1547
1548  if (count < 0)
1549    return (_rl_char_search_internal (-count, bdir, c));
1550  else
1551    return (_rl_char_search_internal (count, fdir, c));
1552}
1553#endif /* !HANDLE_MULTIBYTE */
1554
1555#if defined (READLINE_CALLBACKS)
1556static int
1557_rl_char_search_callback (data)
1558     _rl_callback_generic_arg *data;
1559{
1560  _rl_callback_func = 0;
1561  _rl_want_redisplay = 1;
1562
1563  return (_rl_char_search (data->count, data->i1, data->i2));
1564}
1565#endif
1566
1567int
1568rl_char_search (count, key)
1569     int count, key;
1570{
1571#if defined (READLINE_CALLBACKS)
1572  if (RL_ISSTATE (RL_STATE_CALLBACK))
1573    {
1574      _rl_callback_data = _rl_callback_data_alloc (count);
1575      _rl_callback_data->i1 = FFIND;
1576      _rl_callback_data->i2 = BFIND;
1577      _rl_callback_func = _rl_char_search_callback;
1578      return (0);
1579    }
1580#endif
1581
1582  return (_rl_char_search (count, FFIND, BFIND));
1583}
1584
1585int
1586rl_backward_char_search (count, key)
1587     int count, key;
1588{
1589#if defined (READLINE_CALLBACKS)
1590  if (RL_ISSTATE (RL_STATE_CALLBACK))
1591    {
1592      _rl_callback_data = _rl_callback_data_alloc (count);
1593      _rl_callback_data->i1 = BFIND;
1594      _rl_callback_data->i2 = FFIND;
1595      _rl_callback_func = _rl_char_search_callback;
1596      return (0);
1597    }
1598#endif
1599
1600  return (_rl_char_search (count, BFIND, FFIND));
1601}
1602
1603/* **************************************************************** */
1604/*								    */
1605/*		   The Mark and the Region.			    */
1606/*								    */
1607/* **************************************************************** */
1608
1609/* Set the mark at POSITION. */
1610int
1611_rl_set_mark_at_pos (position)
1612     int position;
1613{
1614  if (position > rl_end)
1615    return -1;
1616
1617  rl_mark = position;
1618  return 0;
1619}
1620
1621/* A bindable command to set the mark. */
1622int
1623rl_set_mark (count, key)
1624     int count, key;
1625{
1626  return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1627}
1628
1629/* Exchange the position of mark and point. */
1630int
1631rl_exchange_point_and_mark (count, key)
1632     int count, key;
1633{
1634  if (rl_mark > rl_end)
1635    rl_mark = -1;
1636
1637  if (rl_mark == -1)
1638    {
1639      rl_ding ();
1640      return -1;
1641    }
1642  else
1643    SWAP (rl_point, rl_mark);
1644
1645  return 0;
1646}
1647